
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 06-11-2019 08:21 PM
This is a really, really obscure problem, but as it's something someone else could run into, I thought I'd drop it into a short article.
ServiceNow's service catalog items and record producers can include widgets embedded as macro variables. This is a really handy feature as it allows catalog items to be extended and provides a lot of flexibility.
I ran into one really obscure problem, though... the symptoms were... the widget would work perfectly fine when the page first loads, but navigate away from the page (say back to the catalog home page) and then return and the $scope angular object fails to update (ie, the widget appears dead as though it has failed to load). Refresh the page and everything works fine, but navigate away and back again, and... dead...
The funny thing, though, was if I included console.log($scope) in the widget I could see that in BOTH scenarios, the $scope was working perfectly fine and returning the results I expected, but the angular HTML was failing to display those results.
After considerable head scratching, I figured out that ServiceNow have dynamically embedded the widget inside their sc_cat_item widget so the custom widget essentially has TWO different scopes. I found that if I updated BOTH scopes, the widget worked fine under all circumstances.
An example might help...
c.data.results = myDataArray;
console.log(c.data.results);
This works fine when the page first loads. The angular HTML works perfectly (with the results being written to the browser console as confirmation).
But navigate away from the page and return again, and although the console still accurately shows the contents of c.data.results, the angular HTML fails to render those results.
As soon as I updated BOTH scopes, the problem was solved.
c.data.results = myDataArray;
var parentScope = window.angular.element('#sc_cat_item').scope()
var widgetData = parentScope.$parent.c.data.sc_cat_item._fields.current_leave.widget.data;
widgetData.results = myDataArray;
In this example, current_leave is the name of the variable macro (so if you run into this and want to use this approach, you'll need to change that), but this allowed BOTH scopes to be updated with the same results and everything worked fine.
Have fun
- 2,802 Views