Search code examples
javascriptember.jsember-cli

why .pushObject method is undefined in ember


"model.pushObejct is not a function" error. i am trying build an to do list app..and while updating an object it says model.pushObject is not a function.

<ul class="hand">
  {{#each @model as |item|}}
  {{#if item.id}}
  <li>{{item.title}}</li>
  <button onclick={{fn this.delete @model item}} type='button'>delete</button>
  {{/if}}
  {{/each}}
</ul>
<form onsubmit={{fn this.submit @model}}>
  <Input placeholder='Add todo' type='text' value={{this.text}} 
    onchange={{fn this.onChange}} />
  <button type='submit'>Add</button>
  {{log @model}}
</form>
  @tracked
  text = "";

  @action
  submit(model, event) {
    event.preventDefault();
    const i = model[model.length - 1].id + 1;
    const newTodo = {
      id: i,
      title: this.text
    };
    model.pushObject(newTodo);
    model=model;
    console.log("add", model);
  }

  @action
  onChange(e) {
    this.text = e.target.value;
  }
  @action
  delete(model, item) {
    const index = model
      .map((file, index) => {
        if (file.id === item.id) {
          set(item, "id", null);
          set(item, "title", null);
          return index;
        }
      })
      .filter(id => id !== undefined);
    model.splice(index[0], 1);

i tried model.push it is working but the {{#each}} is not updating the information..

  @action
  submit(model, event) {
    event.preventDefault();
    const i = model[model.length - 1].id + 1;
    const newTodo = {
      id: i,
      title: this.text
    };
    model.push(newTodo);
    model=model;
    console.log("add", model);
  }

object is pushed but UI is not updated:


Solution

  • pushObject does not exist on native JS Arrays, docs here

    To use pushObject, you must enable prototype extensions. Here are the relevant docs for enabling/disabling.

    An alternative native way would be to do this.array = [...this.array] as that will update the tracked reference (tracking updates operate on references, rather than values.

    An another way would be to use a reactive array, like this:

    import { TrackedArray } from 'tracked-built-ins';
    
    // ...
    todos = new TrackedArray();
    
    // ...
    todos.push({ /* new object */ });