# Custom Commands ( Optional )

Our graphic is looking pretty good so far. We can handle loading in some data, animating in and out, as well as advancing between titles. But, broadcasting is never as simple as load, play, next, and stop. There are usually situations where going to the first title or backwards by one title is needed. To handle those, we will add a `reset` and `previous` function to our graphic.  &#x20;

### Resetting to the Beginning

It is typically easier to reset a graphic than it is to remove and reload a graphic. With something as simple as the one created in this guide, you may not notice any lag. But, in a more complex graphic that requires downloading videos or images before running, keeping those assets loaded will save a lot of network and CPU overhead. Let's add our `reset` function right after our `stop` function and then break it down.

```javascript
function stop() { /* Stop function script */ }

function reset() {
    if(currentStep === 0) { // Graphic needs to be loaded
        handleError('The graphic is already on its first item.');
        return;
    }
    let animation;
    if(state === 1) { // Graphic is not visible
        currentStep = 0;
        animation = () => new Promise((resolve, reject) => {
            activeStep = 0;
            applyData();
            resolve();
        });
    } else if(state === 2) { // Graphic is visible 
        currentStep = -1;
        animation = () => new Promise((resolve, reject) => {
            activeStep = -1;
            resolve();
        }).then(next);
    } else {
        handleError('Cannot reset a graphic that has not been loaded.');
        return;
    }
    addPlayOutCommand(animation);
}

async function remove() { /* Remove function script */ }

```

The first thing we want to do is make sure the graphic has been loaded. If it is, we can check the state again to determine if the graphic is visible. A state of `1` tells us the graphic is hidden while a state of `2` is visible. We will need to increment our `currentState` and `activeState` differently according to the current state. When the graphic is not visible, we can skip any animations and change the data immediately. Since the `next` function is never called, the `currentState` and `activeState` variables are never incremented. Which means we can set them both to the first item in the array, or `0`. When the graphic is visible, we will call `next` function which will increment `currentState` and `activeState`. So, we set them both to `-1` to offset this.

### Going Backwards

Going to the previous title requires a little bit more work than resetting but, it is still very straight forward.&#x20;

```javascript
function previous() {
    if(currentStep > 0) { // Check that we can go backwards
        let animation;
        if(state === 2) { // If the graphic is visible, animate backwards
            currentStep -= 2;
            // Create the promise that will eventually update 
            // the activeState and call next
            animation = () => new Promise((resolve, reject) => {
                activeStep -= 2;
                resolve();
            }).then(next);
        } else if(state === 1) { // If the graphic is hidden, just change the data
            currentStep -= 1;
            animation = () => new Promise((resolve, reject) => {
                activeStep -= 1;
                applyData();
                resolve();
            });
        } else {
            handleError('Graphic can not go back one title in the current state.')
            return;
        }
        addPlayOutCommand(animation);
    } else {
        handleError('There is no graphic to go backwards to.');
    }
}
```

To begin, let's ensure that we are not on this first title. If we are not then, we check the graphic's `state` is correct. But, this time the graphic can be in a few different states. If the graphic has been played, state `2`, then we will make sure we are not on the first title. If we are not, then we will remove `2` from the `currentStep` and `activeStep` variable, since `next` is going to increment it by `1`, and then call `next`. If the graphic is in state `1`, loaded but not yet played, we will remove `1` from `currentStep` and `activeStep` variables and apply the text data.

That will finish up our `reset` and `previous` functions.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://chrisryanouellette.gitbook.io/casparcg-html-template-guide/javascript/custom-commands-optional.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
