0

I want to update the todoList in my PARENT COMPONENT after I have added a new item in my child using the AddItem() method. Nothing gets added the first time. EX. if I add "take test" doesn't get render, then if I add "take shower" doesn't get rendered but now "take test" does. Then if I add "take a leak" "take shower" gets rendered.

PARENT COMPONENT

firstUpdated(changedProperties) {
    this.addEventListener('addItem', e => {
      this.todoList = e.detail.todoList;
    });
  }

  render() {
    return html`
      <p>Todo App</p>
      <add-item></add-item>//Child item that triggers the add
      <list-items todoList=${JSON.stringify(this.todoList)}></list-items>
    `;
  }

CHILD COMPONENT

AddItem() {
    if (this.todoItem.length > 0) {
      let storedLocalList = JSON.parse(localStorage.getItem('todo-list'));
      storedLocalList = storedLocalList === null ? [] : storedLocalList;
      const todoList = [
        ...storedLocalList,
        {
          id: this.uuidGenerator(),
          item: this.todoItem,
          done: false
        }
      ];

      localStorage.setItem('todo-list', JSON.stringify(todoList));
      this.dispatchEvent(
        new CustomEvent('addItem', {
          bubbles: true,
          composed: true,
          detail: { todoList: storedLocalList }
        })
      );
      this.todoItem = '';
    }
  }

  render() {
    return html`
      <div>
        <input .value=${this.todoItem} @keyup=${this.inputKeyup} />
        <button @click="${this.AddItem}">Add Item</button>
      </div>
    `;
  }
Patricio Vargas
  • 5,236
  • 11
  • 49
  • 100
  • Try writing `eventlistener` in connected call back instead.. or approach 2: replace this.addEventLister to document.addEventListener.. – shabarinath Sep 06 '19 at 21:39
  • 1
    Is the problem that no event is being dispatched or that no item is being added to the list? Could you edit your question to include a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). We can't reproduce the issue in order to help you solve it because, for example, you've omitted the code that updates `this.todoItem` (which I can only assume is in `this.inputKeyup`). – Jordan Running Sep 06 '19 at 21:41
  • As an aside, is there a reason you chose to bind the event listener in `firstUpdated` rather than doing so in the template, e.g. ``? – Jordan Running Sep 06 '19 at 21:46
  • @shabarinath I have updated the code. The code is not adding the item to the list BUT only when I add an item again. EX. if I add "take test" doesn't get render, then if I add "take shower" doesn't get rendered but now "take test" does. – Patricio Vargas Sep 07 '19 at 01:17
  • @JordanRunning uhmm nope. This is my first app with Polymer so obviously I have no clue what I'm doing lol. I have updated my question – Patricio Vargas Sep 07 '19 at 01:20
  • @JordanRunning I did this `````` and still experiencing the rending issue – Patricio Vargas Sep 07 '19 at 01:38
  • 1
    @PatricioVargas why do u need localstorage., Also., have you initailised `todoItem` in `static get properties` ?.. like `static get properties() { return { todoItem: {type: Array, Observer: '_itemsUpdated' }}`., in `_itemsUpdated` ., `_itemsUpdated(newValue,oldValue){if(newValue){-- write your code here.. no event listeners required}}`.. one more point., dont forget to initialise `todoitem` in `constructor`.. `constructor(){ this.todoItem = [] }`.. constructor just initialises. Observer observe changes to array & triggers function. there u can update your array – shabarinath Sep 07 '19 at 02:48
  • 1
    @PatricioVargas perhaps this blog https://jsabarinath.wordpress.com can help you understanding polymer for starters. Since you are curious., this blog has some related posts which can give solution to your questions. – shabarinath Sep 07 '19 at 02:55
  • @shabarinath local storage is just for this example to store the data somewhere. This is my first polymer app so I just felt like using localstorage and yes. I have set the todoList array in my properties and initialized it in the constructor. Can you put that comment in an answer please? Thanks so much! ill look at your blog – Patricio Vargas Sep 07 '19 at 03:18
  • @PatricioVargas Thanks Iam helpful. Perhaps you can accept my answer. – shabarinath Sep 07 '19 at 03:26

2 Answers2

1

You need to set properties for todoItem

static get properties() {

  return { 
    todoItem: {
    type: Array, 
    Observer: '_itemsUpdated' 
    }
  }
  constructor(){ 
    this.todoItem = [] 
  }
  _itemsUpdated(newValue,oldValue){
  if(newValue){
    -- write your code here.. no event listeners required
    }
  }

In above code., We need to initialise empty array in constructor.

Observer observe the changes to array & triggers itemsUpdated function which carries oldValue & NewValue. In that function., you can place your logic.

No Event Listeners required as per my assumption

shabarinath
  • 548
  • 3
  • 18
  • but how am I sending the updated array all the way to the parent component? – Patricio Vargas Sep 07 '19 at 03:32
  • @PatricioVargas sry., i was in assumption that it was single component while answering. you can keep eventListeners and use `requestUpdate` method for DOM re rendering in `lit-html` (as i can see you are trying to combine Polymer & Lit from your code).. `this.addEventListener('addItem', e => { this.todoList = e.detail.todoList; this.requestUpdate(); });`.. see lit-html life cycle here.. https://lit-element.polymer-project.org/guide/lifecycle – shabarinath Sep 07 '19 at 03:55
1

Found my error. I was passing to detail: { todoList : storedLocalList } which is the old array without the updated value.

 AddItem() {
        if (this.todoItem.length > 0) {
          let storedLocalList = JSON.parse(localStorage.getItem('todo-list'));
          storedLocalList = storedLocalList === null ? [] : storedLocalList;
          const todoList = [
            ...storedLocalList,
            {
              id: this.uuidGenerator(),
              item: this.todoItem,
              done: false
            }
          ];

          localStorage.setItem('todo-list', JSON.stringify(todoList));
          this.dispatchEvent(
            new CustomEvent('addItem', {
              bubbles: true,
              composed: true,
              detail: { todoList: todoList }
            })
          );
          this.todoItem = '';
        }
      }
Patricio Vargas
  • 5,236
  • 11
  • 49
  • 100