How to get the "widget-sc-cat-item-v2" to load a different catalog item?

DrewW
Mega Sage
Mega Sage

It was requested that I build a Q/A widget that will guide the user to the correct catalog item to order.  Sort of like the old wizards.  So basically the user is presented with a list of questions and they pick one and then a new list of questions comes up and they pick one, eventually it ends with a catalog item being displayed.  So this was simple enough to do but I there are several requirements that have caused me an issue.  First is that if the use picks the wrong thing they have to be able to go back, ok easy.  Second is that the page should not reload, ok no problem.  So now that I have done those what happens is when you pick something that loads "Cat Item A", then go back and pick something else that should load "Cat Item B" what you see is "Cat Item A".  I have reviewed the code for the "widget-sc-cat-item-v2" and pushed in a different sys_id, I have triggered events that cause the widgets scope to update but even though the scope data shows that it has the new catalog item it still does not update the user interface to show it.  When I try a "$scope.$apply()" I get an error that $apply already in progress.

One of the first things I did was used "$sp.getWidget" server side to just get the whole widget again and set it on the page like I do the first time it loads but that causes a whole lot of client side errors when you try and load it a second time.  As far as I can tell angular is designed to keep a child component in memory and to replace it you have to destroy it some how but I have not managed to find a way to do that or comment the widget to load something which I have not managed to do either.  I would rather not have to copy the widget.

Anyone have any thoughts on this?

1 ACCEPTED SOLUTION

DrewW
Mega Sage
Mega Sage

So I noticed after posting this that one of the catalog items had a delivery time that would be displayed and would also be hidden when a new one was selected so something was updating.  What I found is that in the HTML of the widget ServiceNow did things like this

<sp-model form-model="::data.sc_cat_item" mandatory="c.mandatory"></sp-model>

Which is a one time binding that will not change even if the "data.sc_cat_item" changes.  Serves me right to not look over the HTML more carefully.  You can read about one time bindings here.
https://docs.angularjs.org/guide/expression

So to get this to work I had to make a copy of the widget and remove the one time bindings.

After updating the widget to remove the one time bindings all that needs to be done is 

$rootScope.$broadcast("$sp.list.click", { sys_id : <CAT ITEM SYS_ID>});

View solution in original post

1 REPLY 1

DrewW
Mega Sage
Mega Sage

So I noticed after posting this that one of the catalog items had a delivery time that would be displayed and would also be hidden when a new one was selected so something was updating.  What I found is that in the HTML of the widget ServiceNow did things like this

<sp-model form-model="::data.sc_cat_item" mandatory="c.mandatory"></sp-model>

Which is a one time binding that will not change even if the "data.sc_cat_item" changes.  Serves me right to not look over the HTML more carefully.  You can read about one time bindings here.
https://docs.angularjs.org/guide/expression

So to get this to work I had to make a copy of the widget and remove the one time bindings.

After updating the widget to remove the one time bindings all that needs to be done is 

$rootScope.$broadcast("$sp.list.click", { sys_id : <CAT ITEM SYS_ID>});