Sorry, my bad. The #onClick method should be a class property for that to bind properly:
#onClick = (buttonId: any) => {
this.value = buttonId;
this.dispatchEvent(new UmbChangeEvent());
}
Sorry, my bad. The #onClick method should be a class property for that to bind properly:
#onClick = (buttonId: any) => {
this.value = buttonId;
this.dispatchEvent(new UmbChangeEvent());
}
Ah I seee, Why should it be a class property?
Is that because of the callback?
addEventListener('click', () => callback(item.id));
Almost correct! It’s because we were passing it as a reference, so it would get its own little this context.
We needed to pass it as a value instead, which a class property solves.
You could also have used .bind(this):
const container = buttonTemplate.render(settings, this.#onClick.bind(this));
ahh I see
, that’s clever. Thanks again, again, again ![]()
I think it’s a very fancy solution and I find it very interresting. I do find it a bit…complex(?) for what it’s needs to do.
Maybe I’m missing something, but I would just load the blocks (the api call) on connectedCallback, put it in a variable that has @state once the blocks are loaded and that would trigger a rerender, done!
I would not know, I will have a look at state. But at the moment its working. I even have a little notification popup which is neat. The last thing I need to do is make the value = {} rather than a string value =’’ so I can return JSON data I need. But I am working on this problem
. I plan to refer to @jacob as ‘GOD’ for the near future
.
I hear you and there were probably also better ways of doing it with AngularJS back then, but I can appreciate having to convert a solution 1-1 that already worked when learning something new.
Your solution also works, but you need to control loading and error states manually. Now, that is not very hard to do, but @lit/task makes it an absolute breeze once you also consider you can start the tasks manually or x-amount of times or, in this case, have it react to one or more input properties.
This is probably not the only property editor that they have to convert either.
Try this
this.value = { id: buttonId }
Hi @jacob I hope you had a good weekend :). I tried this way. I was doing
this.value = {id: '', colour:'', something:''}.
I need to return multiple values, which I believe will be JSON? And changing ‘value’ to an object as well. However when I debug, ‘value’ is always an array with a single item, ‘id‘, and nothing else
Its not
. But I will certainly read up on @stateset
That’s not valid JSON, though. If you need multiple values, storing them as an array is the way to go, but you need an add and a remove method:
#onChange(settings: any) {
// First convert older values or reset the array
if (!this.value || !Array.isArray(this.value)) {
this.value = [];
}
// Check if the value is already there
const idx = this.value.findIndex(x => x.id === settings.id)
if (idx === -1) {
// Not found - this is the first time seeing this value, so probably a new button
this.value.push(settings);
} else {
// Found - we already have this item, so the user probably clicked it again to remove it?
this.value.splice(idx);
}
this.dispatchEvent(new UmbChangeEvent());
}
The ‘value’ should then become an array. You probably need to play around with the values passed back and forth to the onChange method.
Ahh I see, so I bind that to the button, which makes value an array. Then I can update the array, and if there is an array, the id just gets added and nothing else changed :D. I am a big fan of TypeScript and Lit now ![]()
I saw in the docs I needed to create an object like this in order to get JSON returned server side. I might have of misunderstood though
. Either way I need JSON to create an object server side which is why is was not using an array. An array could work though.
An array (start character [) is still valid JSON, though. It doesn’t need to start with a {.
Hi @jacob
So I have tried just about everything and just wanted to check i am not doing something stupid.
@property({ type: Array }) public value = [{id:''}];
I have an #onChange method. I had to change some syntax. (splice was not working)
I changed this to be === -1?
if (idx === -1) {
.push is also having problems. But I can do this.value = Object.assign(, this.value); to get around that.
#onChange = (settings: any) => {
// First convert older values or reset the array
if (!this.value || !Array.isArray(this.value)) {
this.value = [];
}
// Check if the value is already there
const idx = this.value.findIndex(function (x) { return x.id === settings.id });
if (idx === -1) {
// Not found - this is the first time seeing this value, so probably a new button
this.value.push(settings);
} else {
// Found - we already have this item, so the user probably clicked it again to remove it?
this.value = this.value.filter(item => item.id != settings.id)
}
this.dispatchEvent(new UmbChangeEvent());
}
and I have wired the OnChange event to the button.
@onChange=${callbackOnChange(item)
But now I am in an infinite loop. I presume because this.value now gets changed, maybe by my Object.assign?
Just wanted to check I had not doing anything stupid before working out my infinite loop problem
I’m not sure you should set a default value, but declaring it as an array is probably good:
@property({ type: Array })
public value: Array<Settings> = [];
Good, my bad for getting the logic upside down.
I think the value is readonly, but I’m not sure. You could set the value just fine in the first example, where you set it to a string. Maybe it’s because of the binding:
I think the correct syntax (to preserve the correct “this” context) would be:
@onChange=${() => callbackOnChange(item)}
But maybe Lit can figure it out with the other syntax anyway.
Try to put in a debugger; statement in your callback method and cycle through it in the browser. It should stop the execution if you keep DevTools (F12) open. You might be able to see where it throws you into a loop?
Thanks @jacob ![]()
Thanks @jacob so much. I have it working now. The last thing was changing the return type in umbraco-package.json
Thanks as well @Luuk :’). I forgot you (sorry)