Search code examples
ember.jsember-data

What is the recommended way to make a PUT request to an external API in EmberJS?


I have a simple app that retrieves a record from an external API and displays the value ("day"). The day value can be incremented by passing it into a component with a simple action. My app is retrieving the record correctly and is successfully passing it to the component. But once it has incremented the value I can't figure out the best way to save the record back to the external API.

My route fetches the object like this:

export default Route.extend({
  model() {
    return this.get('store').findRecord('world', '5cb0f8bd3b74cf22b75e1a37', { reload: true });
  },
})

This is my model:

import Model from 'ember-data/model';
import DS from 'ember-data';

const { attr } = DS;

export default Model.extend({
  day: attr('Number'),
});

In my template the day value is mapped to my component with:

<Wait @day={{model.day}}></Wait>

And my component has a button that calls the action like this:

<button {{action "incrementDay"}} class="btn btn-default" aria-hidden="true">Wait</button>

Finally, here is my component:

import Component from '@ember/component';
import { inject as service } from '@ember/service';

export default Component.extend({
  router: service(),
  store: Ember.inject.service(),
  actions: {
    incrementDay() {
      this.day++;
      console.log(this.day);
    }
  }
});

Each time I press the button the console outputs the incremented number successfully, but I'm not sure how to then save the changes back to the API. What is the best way to make a PUT request back to the API with the changed data?


Solution

  • You may want to pass the whole model to your component. like this:

    <Wait @someBetterName={{@model}} />
    

    (as an aside, you may want to have your model be a hash of things so you can use more canonical names for things)

    async model() {
      let myModelA = await this.store...
      // ...
      return {
        modelA: myModelA,
        modelB: myModelB,
    
      }
    }
    

    but then inside Wait, you could have your action do this:

      actions:{
        async incrementDay() {
          let day = this.someBetterName.day;
          this.someBetterName.set('day', day + 1);
    
          await this.someBetterName.save();
          console.log('saved!')
        }
      }