How to access top level meta key from json-api server's 200 response when calling ember data's destroyRecord()

后端 未结 2 390
栀梦
栀梦 2021-01-18 13:29

I\'m working on an Ember app that is using Ember Data and the now default json-api adapter.

According to the json-api spec (http://jsonapi.org/format/#crud-deleting)

相关标签:
2条回答
  • 2021-01-18 14:00

    Ember does not support meta for single model requests (find,save and destroyRecord) at the moment!

    If you want this you have to hook into ember internals.

    The following code uses ember internals from ember 2.3 and may break in future versions!

    There is the undocumented _metadataFor function on the store that gives you the last metadata for a given type. I use a custom initializer to always save it to the Model:

    import Ember from 'ember'; 
    import DS from 'ember-data';
    const {set} = Ember;
    export function initialize(application) {
      DS.Model.reopen({
        meta: null,
        didCommit() {
          this._super(...arguments);
          set(this, 'meta', this.store._metadataFor(this.constructor.modelName));
        }
      });
    };
    
    export default {
      name: 'meta',
      initialize: initialize
    };
    

    After this you can do model.save().then(() => console.log(model.get('meta'))) or model.destroyRecord.then(() => console.log(model.get('meta'))).

    Maybe checkout this ember-twiddle.

    0 讨论(0)
  • 2021-01-18 14:10

    After upgrading to Ember 2.6.1 and Ember 2.6.1 I was no longer able to access the store._metadataFor property.

    To get access to the metadata from a particular call I now override the serializer for the model and add a meta property to the model itself that simply passes through the metadata.

    As an example I have a record type called vote which when saved returns some metadata.

    For the model I do the following:

    // Vote Model (/app/models/vote)
    export default DS.Model.extend({
      vote: DS.attr('number'),
      // Since i don't provide a transform the values for meta are passed through in
      // raw form
      meta: DS.attr()
    });
    

    Then in the serializer for the vote model I do the following:

    // Vote serializer (/app/serializers/vote)
    import DS from "ember-data";
    
    export default DS.JSONAPISerializer.extend({
      normalizeSaveResponse(store, primaryModelClass, payload, id, requestType) {
        // The metadata in the payload does get processed by default and will be
        // placed into a top level `meta` key on the returned documentHash
        let documentHash = this._super(store, primaryModelClass, payload, id, requestType);
    
        // Make sure we always have an empty object assigned to the meta attribute
        if(typeof(payload.meta) !== 'object'){
          payload.meta = {};
        }
    
        // Move the metadata into the attributes hash for the model
        documentHash.data.attributes.meta = payload.meta;
    
        return documentHash;
      }
    });
    

    Note that in the above example I'm only adding in metadata to the vote model when making a save call to the store. If you wanted to always add in the metadata then you would override the normalize method instead of the normalizeSaveResponse method.

    Then you can access a meta field in the results of your save call.

    let vote = self.store.createRecord('vote', {
       vote: voteValue
    });
    
    vote.save().then(function(result){
       // this will now contain your metadata
       console.info(result.get('meta'));
    });
    
    0 讨论(0)
提交回复
热议问题