5 Tips and Workarounds for Angular/JS Extension Development

Factless Fact Tables
July 15, 2019
Using the Python Node in KNIME to Perform Granger Causality Tests
July 29, 2019
Show all

This article provides a few small tips and tricks to ease some of the headaches of developing Angular/JS extensions for Qlik.

1. When using jQuery, make sure you are utilizing unique selectors for a given instance of the extension.

Multiple instances of an extension can exist on a single sheet. If using jQuery, it is easy to select (and accidentally edit) all instances of an extension on a sheet. To prevent this, each instance of the extension should have its own id.

More advanced users may want to consider using the objectId that Qlik assigns to visualizations, but those can be difficult to track down.

We at NuWave have found an easy method to utilize unique selectors: Generate a random number, place it in a wrapper div in the html, then use that number for all selections.

Figure 1: Generate a random number id in the main js file for extension.

Figure 2: In a directive, use the generated random number as the id attribute of a wrapper div, which is used for selections.

2. Use Validated and a broadcast() (with a Timeout) for re-drawing in Angular extensions.

When creating an extension that needs to redraw (ie: on selection or property changes), Qlik recommends using the Validated event. Qlik’s documentation describes this event as one that: “occurs if the data has been recalculated and new valid data is available.” Calling redraw functions can be done when bound to this event.

However, we at NuWave have found that Validated can be triggered before “new valid data” is truly available. We’ve experienced cases where attempting to get new data after Validated results in old data, not new data (especially for larger hypercubes). A Timeout function can help with that timing, but this seems like something Qlik will need to fix in the future.

Note that the Validated event only exists when an extension is not in Snapshot mode.

Figure 3: In the main extension js file, bind a function to the Validated event. Then set a timeout to broadcast a call to all directives that need to redraw.

3. If re-drawing and using the backendApi, pass the new backendApi object through the broadcast.

This tip applies to extensions that make use of directives. Along with the Tip #2, it is important to pass the backendApi from the extension’s main scope to any directives that will need to use it. Otherwise, the directives’ scoped backendApi will have properties on it associated with the hypercube that existed when the extension was first drawn. The extension may not correctly update with new data because of this.

Passing the backendApi object through the broadcast allows the backendApi properties to be updated on each Validated event call and propagate to all directives.

Figure 4: In a directive, handle calls to redraw and update the backendApi.

4. Put calls that interact with backend Qlik functions into services.

This tip deals more with the concept of AngularJS’ Separation of Concern: Place any backend calls into Angular services. It is a great way to create modularized code that can be easily added across multiple extensions.

Some useful functions to have in a Qlik service include: getData, getProperties, setProperties, save, and selectValues.

5. When exporting an extension, the theme does not exist, but can be retrieved by name.

It is relatively easy to apply styling from the theme of an app into an extension using Qlik’s ‘app’ object. However, the ‘app’ object (and its theme) is not accessible when an extension is being used in an export. This results in un-styled exports.

If this is an issue, one workaround is to have a theme dropdown on the extension properties. Because all themes can be retrieved from the ‘qlik’ object, it is possible to match to the name of the desired theme and still utilize it.

Figure 5: Check for existence of the ‘app’ object. If it does not exist, use the tableTheme property to get and use correct theme.

Leave a Reply

Your email address will not be published. Required fields are marked *