1

I have a variable newtags that contains tags added by the user. When a tag is added it's shown on the interface when it's double-clicked it should disappear from the interface, for this matter I used @track and it works fine.

At the same time I need to set this variable by the parent component on render for this I should use @api but it seems like I can't use both simultaneously.

Parent Component

<template if:true={showScreen2}>
       <c-screen2 ongetgeneralinfo={handleGeneralInfo} 
                  title={title}
                  description={description}
                   newtags={newTags}>
        </c-screen2>
</template>

Screen2 Component

@api newtags = [];
handleTagInput(event){
        if(event.keyCode === 13){
            this.newtags = [...this.newtags, {name : event.target.value}];


         }
        }
removeTag(event){
        let tagToRemove = event.target.dataset.id;

        for(let i = 0; i < this.newtags.length; i++) {
            let obj = this.newtags[i];
            
            if(obj.name == tagToRemove){
                console.log('#');
                this.newtags.splice(i, 1);
                console.log(this.newtags);
            }
        }
    }

In the console:

enter image description here

But in the Interface, I still can see 3 tags

enter image description here

2
  • Don't assign values back to @api variable. Jun 16, 2022 at 15:22
  • 1
    As a side note, I see this often; you should choose a more descriptive name than screen2, as it doesn't convey what the screen is, and even worse, if you have to change the order around, it can become tricky to maintain. Good variable names are a best practice.
    – sfdcfox
    Jun 16, 2022 at 18:56

1 Answer 1

6

You cannot combine @track, @wire, and/or @api with each other. The child should notify the parent that it needs to remove the tag:

handleDoubleClick(event) {
  this.dispatchEvent(
    new CustomEvent(
      'removetag', 
      { detail: { id: event.target.dataset.id } }
    )
  );
}

Which the parent then handles:

<!-- markup -->
onremovetag={handleRemoveTag}

handleRemoveTag(event) {
  this.newTags = this.newTags.filter((tag) => tag.id !== event.detail.id);
}

At this point, the page will refresh as you expect.

To be clear, do not attempt to modify an @api attribute directly, and avoid using @api get/set properties, as they are not fully reactive.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .