devour-js / devour-client

Don't just consume your JSON API, Devour it...
https://www.npmjs.com/package/devour-client
ISC License
429 stars 89 forks source link

update and patch with define confusion #171

Closed jarekskuder closed 5 years ago

jarekskuder commented 5 years ago

Hi,

i define model like this:

let Api = new JsonApi({
  apiUrl: API_URL,
  pluralize: false
});

Api.define('Country', {
  _id: '',
  name: '',
  comment: '',
  iso2: '',
  isDeleted: true,
  createdAt: '',
  modifiedAt: '',
  createdBy: {
    jsonApi: 'hasOne',
    type: 'User'
  },
  modifiedBy: {
    jsonApi: 'hasOne',
    type: 'User'
  }
});

As i understand, if my API response has type: "Country", i must define it like that.

This is my backend API:

test

To get list of countries, i call it like this:

Api.findAll('countries')
      .then((data) => {
        if (this._isMounted) {
          console.log(data);
          this.setState({countries: data.data});
        }
      })
      .catch((error) => {
        console.log(error);
      });

I really don't understand why i must write in findAll the URL and not model, but ok, atleast it works.

Now comes the fun part. When i want update or patch or create, example:

Api.update('countries', {
        _id: this.props.match.params.id,
        name: this.state.country.name,
        iso2: this.state.country.iso2,
        comment: this.state.country.comment,
        isDeleted: this.state.country.isDeleted,
        modifiedAt: now.toISOString()
      })

OR

Api.one('countries', this.props.match.params.id).patch({
           _id: this.props.match.params.id,
        name: this.state.country.name,
        iso2: this.state.country.iso2,
        comment: this.state.country.comment,
        isDeleted: this.state.country.isDeleted,
        modifiedAt: now.toISOString()
      });

I get this:

Error: API resource definition for model "countries" not found. Available models: Country

But when i write:

Api.update('Country', {
        _id: this.props.match.params.id,
        name: this.state.country.name,
        iso2: this.state.country.iso2,
        comment: this.state.country.comment,
        isDeleted: this.state.country.isDeleted,
        modifiedAt: now.toISOString()
      })

OR

Api.one('Country', this.props.match.params.id).patch({
           _id: this.props.match.params.id,
        name: this.state.country.name,
        iso2: this.state.country.iso2,
        comment: this.state.country.comment,
        isDeleted: this.state.country.isDeleted,
        modifiedAt: now.toISOString()
      });

Devour client builds and tries to call PATCH /Country/{id} but gets 404 error back, since the actual URL is /countries/{id} (as per REST standard?). Can someone help? I'm going crazy about this and can't figure it out...

Auspicus commented 5 years ago

You can use the optional parameter collectionPath to tell devour where to find your resource ie:

Api.define('Country', {
  _id: '',
  name: '',
  comment: '',
  iso2: '',
  isDeleted: true,
  createdAt: '',
  modifiedAt: '',
  createdBy: {
    jsonApi: 'hasOne',
    type: 'User'
  },
  modifiedBy: {
    jsonApi: 'hasOne',
    type: 'User'
  }
}, {
  collectionPath: 'countries'
});

Devour will now make requests to /countries when talking to the Country model. So this should work:

Api.one('Country', this.props.match.params.id).patch({
           _id: this.props.match.params.id,
        name: this.state.country.name,
        iso2: this.state.country.iso2,
        comment: this.state.country.comment,
        isDeleted: this.state.country.isDeleted,
        modifiedAt: now.toISOString()
      });
jarekskuder commented 5 years ago

Thank you, it worked! :)