Reputation: 1020
I'm working on a custom carrousel in an Angular app.
For each element in the carousel, the user can write a caption, but only one by one (for the selected element at the time).
So, what I did was to create only one input and to react on its event (input) and update the caption for the selected element as follows:
<input
matInput
formControlName="caption"
maxlength="500"
placeholder="Write caption"
(input)="onCaptionChanged($event?.target?.value)"
/>
onCaptionChanged(value: string) {
this.galleryAttachments = this.galleryAttachments.map((x) =>
x.attachment.id === this.selectedAttachment.id
? { ...x, attachment: { ...x.attachment, caption: value } }
: x
);
}
It works fine but, by doing this
{ ...x, attachment: { ...x.attachment, caption: value } }
the object reference is changed which leads to flickering on the interface.
I also tried to get the selected element and to update its property value, like this:
const current = this.galleryAttachments.find(x => x.attachment.id === this.selectedAttachment.id);
current.attachment.caption = value;
but Angular throws the Cannot assign to read-only property
error.
Is there a possibility to change an object property value without changing the object reference?
Or what should I do to avoid the flickering?
Upvotes: 0
Views: 1146
Reputation: 4790
While you can definitely "hack around" it, the question you should ask yourself is not "How can I do it" but rather "Why should I do it?".
The author of the class you're trying to change definitely had a reason to mark this property as a read only. If that's your proprietary code - change the property to NOT be read only (and handle all changes that it causes). If it's not - perhaps you should either contact the author, change the library to a different one, or write the feature yourself?
The thing is, while it might work NOW it might NOT work after a future update of either Angular or the library. And this will cause much more problems later on.
And to answer your question (how to "hack around" it) - remember that TypeScript is, after all, superset of EcmaScript. So you can use the bracket notation to access any property of the object - and TypeScript will not know the attributes of that property, hence it will not throw an exception.
const current = this.galleryAttachments.find(x => x.attachment.id === this.selectedAttachment.id);
current.attachment['caption'] = value;
Upvotes: 1