496
Views
18
Comments
Solved
Append is not allowed when I try to append a list
Question


Hello,

I'm trying to append a list inside a for loop:


but it gives me this error:


suggestions please ?

2021-09-06 15-09-53
Dorine Boudry
 
MVP
Solution

ok,

the easy solution would be to store / remove selections as they happen, immediately in the database, an then refresh an aggregate serving your bottom list.  

But that's probably not what you are after ?  you want to build the complete list, across serveral Ghu up before saving to the database ??

so your first problem is, when switching to another Ghu which the user already worked on, to preselect the correct Sites in the second dropdown again.

and secondly, the problem you are asking about here, is how to promote a (de)selection in the second dropdown into your bottom list.

So for the second problem ( = your question ), you can't start with a ListClear, because there is also information of other Ghu in there, so you only want to clear the ones for the current Ghu before re-appending them.  So instead do a ListFilter on Ghu <> parameter, then assign SiteItems list to result of this listfilter, then do a ListAppendAll from the inputSelected list.

For the first problem, that might be a bit trickier, haven't worked with these dropdowntags much yet.  

After selecting a new Ghu and refreshing the GetSites in your DropdownGhuTagsOnChanged, you need to filter the previously selected sites from the SiteItems for this particular Ghu, and set them as the Current selection on the Sites dropdown.  


Not sure if the DropDownSetValue will work in the same action as where the list is refreshed, though.   Can't really test it myself, there are broken dependencies.

Dorine

2021-09-06 15-09-53
Dorine Boudry
 
MVP
Solution

i said yesterday 

Not sure if the DropDownSetValue will work in the same action as where the list is refreshed, though.   Can't really test it myself, there are broken dependencies. 

Turns out it is not that simple.

i had a try today, and my suspicion was correct : in logic that happens between a fetch of data to source a dropdowntags, and the actual rendering of the dropdowntags, you can't use SetValue to preselect some value(s), it needs to be rendered first.  Examples would be an action where you refresh the source (like you are doing here) or an OnAfterFetch.

I used to make my own Système D, working with a boolean, and reacting to that boolean inside the OnRender.  With the added annoying warning of potential loop, not ideal...

But I just happened to be exploring the Javascript API of Outsystems today, and it offers the perfect tool for this : the $public.View.render promise.

See attached oml for a demonstration, just make sure to use an existing user to test (i used my own user id) and to reset between each test.

Dorine

QDR_HowHardCanItBe.oml
UserImage.jpg
you asen

it works, thank you so much :)

2022-05-11 15-38-46
Diogo Pacheco

Hello @you ass ,

If you are trying to append to a list that is being iterated you can't do it. What you can do is use an auxiliar list. Do a listappendall at the beggining of the list to copy from original to aux and then do the append to the aux. At the end replace the existing values from the original with the ones in the aux.

UserImage.jpg
you asen

thanks, but what do you mean by  auxiliar list ?

2022-05-11 15-38-46
Diogo Pacheco

Create a variable with the same type of the original list and use this variable as an auxiliar list.

2021-09-06 15-09-53
Dorine Boudry
 
MVP

@you ass ,

it looks like you are trying to copy values from one list to another ??  

If so, you are making it far more difficult than it needs to be.  

In many cases, you can just assign one list to the other, so just a simple Assign from your actions intput list to your local site list.  If the listitems of both don't have the same datatype, Outsystems will give you the opportunity to specify the 'mapping' to be used

So in your case, it would be 

An alternative is to do a listclear, followed by a listAppendAll.  Here again, you will have to do the same mapping if structures are not the same.

Although both of the above will often work, it won't for lists with sublists of different structure, and I find it a bit fragile, for example, if you later rename attributes in your target list, the mapping doesn't get transferred for the new name but just disappears, little things like that.

If you want something a bit more robust, you can also iterate + append after the listclear.  It will also not automatically get the assignment of target list correct after a changed attribute name, but at least, you get a warning, so you know something is wrong.  And you still see the old assignment, so you can just copy paste it to the newly named attribute.

Dorine

UserImage.jpg
you asen

Thanks a lot for the answer..but this is not the same my usecase, I have created a new post:

https://www.outsystems.com/forums/discussion/88026/how-to-add-and-remove-item-dynamically-from-a-list/#Post373128


I put the .oml if you could help please

2021-09-06 15-09-53
Dorine Boudry
 
MVP

no need to start new posts about the same problem, that's just confusing.

so maybe you can say what you are trying to achieve, i find the user interface also a bit confusing

user can select multiple Ghu, but it seems like you are only showing the Sites in the second dropdown of the last selected Ghu ??  Or is the intention that they only select one Ghu at a time.  In that case, dropdown tabs is a bit odd as widget.

And then they can select multiple sites in second dropdown for the currently selected Ghu (ghu parameter) ?

And then in the list below, you want a complete list of what was selected, for current but also for other Ghu ?

Is this the intention ?

UserImage.jpg
you asen


 Or is the intention that they only select one Ghu at a time  => YES

And then they can select multiple sites in second dropdown for the currently selected Ghu (ghu parameter)  => Yes


And then in the list below, you want a complete list of what was selected, for current but also for other Ghu ? => juste the sites selected by the user



2021-09-06 15-09-53
Dorine Boudry
 
MVP
Solution

ok,

the easy solution would be to store / remove selections as they happen, immediately in the database, an then refresh an aggregate serving your bottom list.  

But that's probably not what you are after ?  you want to build the complete list, across serveral Ghu up before saving to the database ??

so your first problem is, when switching to another Ghu which the user already worked on, to preselect the correct Sites in the second dropdown again.

and secondly, the problem you are asking about here, is how to promote a (de)selection in the second dropdown into your bottom list.

So for the second problem ( = your question ), you can't start with a ListClear, because there is also information of other Ghu in there, so you only want to clear the ones for the current Ghu before re-appending them.  So instead do a ListFilter on Ghu <> parameter, then assign SiteItems list to result of this listfilter, then do a ListAppendAll from the inputSelected list.

For the first problem, that might be a bit trickier, haven't worked with these dropdowntags much yet.  

After selecting a new Ghu and refreshing the GetSites in your DropdownGhuTagsOnChanged, you need to filter the previously selected sites from the SiteItems for this particular Ghu, and set them as the Current selection on the Sites dropdown.  


Not sure if the DropDownSetValue will work in the same action as where the list is refreshed, though.   Can't really test it myself, there are broken dependencies.

Dorine

UserImage.jpg
you asen

the senario is, every time a user select a Ghu a set of sites appear on the second dropdownlist(this is already done), the challenge is when a user check on site or more I need to save these values in an aux variable, in case the user change he Ghy I will not lose  them.

and the same is for remove (uncheck), in case the user uncheck a site I need to compare with the aux variable and update it.

2021-09-06 15-09-53
Dorine Boudry
 
MVP

what i describe above will do that for you.  

Instead of maintaining and comparing with aux lists, it just removes all the ones from the current Ghu and then adds them.  Don't know what more to say.


UserImage.jpg
you asen

Could you provide the .oml please ? because I did make it work with what you described above.

I'm getting duplicated items

2021-09-06 15-09-53
Dorine Boudry
 
MVP

nah sorry,

i have already closed Service Studio, and as you had broken dependencies, I could not publish or test, so it's all gone.

But those screenprints I shared is all you have to do, can you share exact same screenprints of what you have done, and do some debugging to see where exactly the duplicates start ?

One thing that I could imagine, is that you are not passing the right Ghuid in the ListAppend (first screenprint)

UserImage.jpg
you asen

thanks a lot for your time. it is very nice of you :)

UserImage.jpg
you asen

one more question please :

is it a new variable or what ? because I dont find it.

2021-09-06 15-09-53
Dorine Boudry
 
MVP

sorry you asen,

didn't see this reply of yours, I already replied in your other post how you can reference a widget's id.

2021-09-06 15-09-53
Dorine Boudry
 
MVP
Solution

i said yesterday 

Not sure if the DropDownSetValue will work in the same action as where the list is refreshed, though.   Can't really test it myself, there are broken dependencies. 

Turns out it is not that simple.

i had a try today, and my suspicion was correct : in logic that happens between a fetch of data to source a dropdowntags, and the actual rendering of the dropdowntags, you can't use SetValue to preselect some value(s), it needs to be rendered first.  Examples would be an action where you refresh the source (like you are doing here) or an OnAfterFetch.

I used to make my own Système D, working with a boolean, and reacting to that boolean inside the OnRender.  With the added annoying warning of potential loop, not ideal...

But I just happened to be exploring the Javascript API of Outsystems today, and it offers the perfect tool for this : the $public.View.render promise.

See attached oml for a demonstration, just make sure to use an existing user to test (i used my own user id) and to reset between each test.

Dorine

QDR_HowHardCanItBe.oml
UserImage.jpg
you asen

it works, thank you so much :)

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.