Skip to content

Panel Queries

Panel queries are the main way of fetching results, such as products or ads from eSales. With the JavaScript library panels can be fetched by using the panel function.

The following code snippet fetches the panel /product-page with arguments window_first=1, window_last=10, and filter=category[book] from the instantiated api object.

    api.panel('/product-page', {
        window_first: 1,
        window_last: 10,
        filter: 'category:\'book\''
    }).then(function(data) {
        renderOnPage(data);
    }).catch(function(data) {
        console.log('Error: ', data);
    });

The structure of the object returned by the panel query depends on the structure of the panel /product-page. Panels are configured in eSales by building a tree structure of areas and backfills. This tree structure is converted by the Web API to a flat JSON-structure in the following format:

// e.g. a product page
Area-1
    Result-1
    Result-2
    ...
Area-2
    Result-1
...

Here is an example using the following visualised panel tree structure:

// Visualisation example

                      [Product Page]
      ┌─────────────────────┼─────────────────────┐
Ads by Products     Product Information     [For Customer]
                                   ┌──────────────┴──────────────┐
                      Recommend Based on Product     Recommend Based on Customer

The root panel "Product Page" is a zone and meant to be used on a product page. It contains panels for related ads and product information for the viewed product. It also includes a zone named "For Customer" with two sub-panels for recommendations.

If a panel request is missing required arguments the request will fail, it will be included in the result but will not have any products. The subpanel will include an error property that describes the error.

In the following example based on the tree structure above, the panel "Recommend Based on Product" is failing due to a request missing argument. Return results from eSales Web API looks like this:

JSON
    {
    "status": 400,
    "response": {
        "adsByProducts": [{
            "name": "ads-by-products",
            "ticket": "Oy9wcm9kdWN0LXBhZ2UvYWRzLWJ5LXByb2R1Y3RzOyM7IzsjOyM7IzsjOyM7",
            "path": "/product-page/ads-by-products",
            "description": "Ads associated with the specified products.",
            "displayName": "Ads by Products",
            "attributes": {},
            "resultType": "ads",
            "ads": [{
                "key": "ad7_banner",
                "ticket": "Oy9wcm9kdWN0LXBhZ2UvYWRzLWJ5LXByb2R1Y3RzO2FkN19iYW5uZXI7IzsjOyM7IzsjOyM7",
                "campaignKey": "package",
                "startTime": "2012-06-01T00:00:00+02:00",
                "included": "campaign:\u00274001648\u0027",
                "related": "category:\u0027movie\u0027",
                "liveProducts": 0,
                "attributes": {
                    "title": ["3 DVDs For 99 SEK"]
                },
                "products": []
            }, {
                "key": "ad2_banner",
                "ticket": "Oy9wcm9kdWN0LXBhZ2UvYWRzLWJ5LXByb2R1Y3RzO2FkMl9iYW5uZXI7IzsjOyM7IzsjOyM7",
                "campaignKey": "low_prices",
                "endTime": "2030-01-01T00:00:00+01:00",
                "included": "category:\u0027game\u0027 AND price:\u00279900\u0027 AND campaign:\u00274007547\u0027",
                "related": "category:\u0027game\u0027",
                "liveProducts": 0,
                "attributes": {
                    "title": ["Games for 99 SEK"]
                },
                "products": []
            }]
        }],
        "productInformation": [{
            "name": "product-information",
            "ticket": "Oy9wcm9kdWN0LXBhZ2UvcHJvZHVjdC1pbmZvcm1hdGlvbjsjOyM7IzsjOyM7IzsjOw",
            "path": "/product-page/product-information",
            "description": "",
            "displayName": "Product Page",
            "attributes": {},
            "error": "Missing argument: product_key"
        }],
        "forCustomer": [{
            "name": "recommend-based-on-customer",
            "ticket": "Oy9wcm9kdWN0LXBhZ2UvZm9yLWN1c3RvbWVyL3JlY29tbWVuZC1iYXNlZC1vbi1jdXN0b21lcjsjOyM7IzsjOyM7IzsjOw",
            "path": "/product-page/for-customer/recommend-based-on-customer",
            "description": "Products that a specific customer might want to buy.",
            "displayName": "Recommend Based on Customer",
            "reportTag": "recommendation",
            "attributes": {},
            "resultType": "products",
            "products": []
        }, {
            "name": "recommend-based-on-product",
            "ticket": "Oy9wcm9kdWN0LXBhZ2UvZm9yLWN1c3RvbWVyL3JlY29tbWVuZC1iYXNlZC1vbi1wcm9kdWN0OyM7IzsjOyM7IzsjOyM7",
            "path": "/product-page/for-customer/recommend-based-on-product",
            "description": "Products that a specific customer might want to buy.",
            "displayName": "Recommend Based on Customer",
            "reportTag": "recommendation",
            "attributes": {},
            "error": "Missing argument: missingFilter"
        }]
    }
}

Rendering a web page

The JSON-serialised panel result returned by the JavaScript library is designed to be as easy as possible to use from JavaScript templates, mostly tested with Mustache and Handlebars.

Here is an example of a template for the result of the "For Customer" area shown above.

<div>
    {{#forCustomer}}
    <div>
        <h2>{{displayName}}</h2>
        {{#products}}
        <div>
            <a href="products/{{key}}" onclick="api.notify.click('{{ticket}}')">
                More information about {{attributes.title}}
            </a>
        </div>
        {{/products}}
    </div>
    {{/forCustomer}}
</div>

In the case of Mustache, the above template can be used directly together with the panel result:

api.panel('/product-page', {
    presentation_attributes: "title",
    products: "{product_key}"
}).then(function(data) {
    var productPage = Mustache.render(template, data.response);
    $('body').html(productPage);
});

Aborting a panel request

The panel request can be abort by calling the .abort() method on the panel object. Aborting a panel-request will return http status code 0 and a response of Aborted. It will then call the .catch() method on the panel object.

var panel = api.panel('/product-page', { });

panel.catch(function(err) {
    console.log(err.status); // 0
    console.log(err.response); // 'Aborted'
});

panel.abort();
×