Skip to content

Creating a page view counter

Introduction

In this first part we'll create a view that displays the number of times it has been shown. Those old enough to remember webpages from the late 90's know what we're talking about.
We will use the State context object to save and load values from disk on the server.

Note

The complete view can be downloaded from here, but you will still need to follow some of the setup steps for it to work.

Setup

  • In SSF_Tutorials, create a new User Area called PageViewCounter.
  • Open Folder Views Tool and remove all the default Widgets and Link Icons.
  • Create a new Link Icon and leave the default name as is (UnnamedLinkIcon_1).

In the File attribute, select Create a new view in this user area..., change the name to PageViewCounter.Rwav and save the the changes in Folder Views Tool.

Open the newly created view for editing.

  • Remove the default elements.
  • Add a Numeric element with the name NumberOfPageViews.
  • Save the file.

In your browser, navigate to the new User Area and make sure the Numeric element displays correctly.

Note

You will see an error in the Numeric element (< Invalid value >) since we haven't defined a value yet.

Adding the server-side code

In the view root object, on the Javascript tab, open up the ServerSideJS editor and paste the following code. Make sure to save the view when done:

ServerSideJS
// We register two server-side functions and 
// return them (to the server-side context)

return {
    // All registered functions must be async and they all must
    // declare 'args' and 'callInfo' as params.

    getPageViews: async (args, callInfo) => {
        // console.log's in server-side code can be seen by opening
        // the Arrigo Log Viewer in Project Builder:
        // * Select the 'Arrigo BMS' node
        // * Open the Tools menu and select 'Arrigo - View logs'
        // * Enter the number for 'arrigo-services-ssf' and press Enter
        console.log("Getting page views");

        // Just get the single value from the default state file for the path.
        // These files live in Proj:\Arrigo\state
        return await callInfo.context.state.get();
    },
    // 'getPageViews' can now be invoked from client-side code

    setPageViews: async (args, callInfo) => {
        // Set a single value in the default state file for the path.
        // 'pageViews' is the named arg we passed from the client-side code,
        // so therefor it can be found in the args object.
        return await callInfo.context.state.set({data: args.pageViews});
    }
    // 'setPageViews' can now be invoked from client-side code
}

Tip

Read more about logging and server side output in Troubleshooting - Server side logs

Adding the client-side code

Open the OnOpen editor for the root object and paste the following code. Make sure to save the view when done:

OnOpen
// The dot (.) before the server-side function name implicitly adds
// the current path (where the view resides).
//
// 'getPageViews' doesn't take any arguments but we're still required
// to pass an empty object ({})
this.view.call('.getPageViews', {}).then((result) => {

    // Get the result (number) or default to 0 if the result was null/undefined.
    let pageViews = result || 0;

    // Increase the value by one
    pageViews++;

    // Set the new pageViews value to the Numeric
    this.view.NumberOfPageViews.value(pageViews);

    // Save the new value to the state file
    this.view.call('.setPageViews', { pageViews }).then((result) => {
        // console.log's in client-side code will appear in the
        // dev-tools console of the browser
        console.log("New page view value saved");
    });
});

The result

Open your browser and navigate to the area. The first time your view loads it should look like this:

Initial value of 1

Reload the browser a couple of times and verify that the counter increases:

Increased value after reload

Quick review

In this part we registered two ServerSideFunctions which used the State object to set and get data from disk on the server. Since we didn't specify a file when using the State object the data was stored in the default file for the path: Proj:\Arrigo\state\PageViewCounter.AreaFolderView.File.UnnamedLinkIcon_1.File.json

Ideas and improvements

In the next part you will learn how to get/set data in a specific file. Using this technique you could create counters in all areas (sharing a single file) and then create a view that displays a summary of which areas in your project that are most viewed/used.

Hint

You would need to store the counter for each area under separate keys (in the file) to achieve this. Read more about this in the State context object reference.