VasilioRuzanni / angular-modelizer

Simple and lightweight yet feature-rich models to use with AngularJS apps.
MIT License
26 stars 4 forks source link

How to access query results #7

Closed DoctorEJB closed 9 years ago

DoctorEJB commented 9 years ago

We really like the modelizer and have fetch and save working nicely. I am trying to get a query going; e.g.: modelize('receiptSummaryList').query({ currencyCode: 'CAD', paymentTypeId: 12, reconciled: false }).then(...

The REST request and response are working perfectly but I'm trying to figure out how to access the response data - I only see the modelizer specific attributes on the response such as $isCollection, $request, etc. When doing a fetch with the exact same model definition I can see my data attributes in the response.

Could someone post a working sample query which includes accessing the response data?

Thanks!

VasilioRuzanni commented 9 years ago

@DoctorEJB Could you please elaborate on an example of the response from the server? The modelize(...).query(...) expects an Array of items from the server by default (you can override the Collection parse() method to parse it in a custom way as a last resort measure but I think we might work our a simpler solution here).

DoctorEJB commented 9 years ago

Thanks for getting back to me Vasilio! Here is sample JSON of the response: (which is working fine)

{ "list": [ { "id": 353, "receiptNumber": "ABC0003535", "locationFrenchName": "NHQ", "locationEnglishName": "NHQ", "receiptStatusFrenchDesc": "Complet", "receiptStatusEnglishDesc": "Complete", "payerName": "Stevo Edgarino", "receiptDateTime": 1434648489460, "canadianPurchaseOrderValue": "5.00" }, { "id": 475, "receiptNumber": "XYZ0004758", "locationFrenchName": "NHQ", "locationEnglishName": "NHQ", "receiptStatusFrenchDesc": "Complet", "receiptStatusEnglishDesc": "Complete", "payerName": " Lucas", "receiptDateTime": 1438104394720, "canadianPurchaseOrderValue": "30.00" } ], "totalRowCount": 2 }


Model definitions:

var receiptSummary = modelize.defineModel("receiptSummary", { baseUrl: '/the-client/service/purchaseOrder',
receiptNumber: '', receiptDateTime: '', reversed: '', canadianPurchaseOrderValue: '', payemntTypeReferenceNumber: '' });

var receiptSummaryList = modelize.defineModel("receiptSummaryList", { //NB. this URL is used in conjunction woth URL query parameters using Modelizer .query() baseUrl: '/the-client/service/purchaseOrder',
list: modelize.attr.collection({ //collection of receiptSummary modelClass: 'receiptSummary'}) });


The query statement:

modelize('receiptSummaryList').query({ currencyCode: 'CAD', paymentTypeId: 12}).then(...

I looped thru the variables names of the response object:

for (varname in receiptList) { console.log("varname: " + varname); }

varname: $request varname: $loading varname: initialize varname: resourceUrl varname: fetch varname: get varname: where varname: any varname: filter varname: create varname: add varname: remove varname: push varname: pop varname: unshift varname: shift varname: slice varname: set varname: reset varname: _reset varname: _prepareModel varname: _isModel varname: _modelId varname: _addModelReference varname: _removeModelReference varname: serialize varname: toJSON varname: parse varname: clone varname: one varname: many varname: $iid varname: modelClass varname: $isCollection varname: _loadingTracker varname: baseUrl varname: urlPrefix varname: models varname: _idsIndex

Some additional logging:

isCollection: true isModel: undefined toJson: [] models:

many: function (resourceName, options) { "use strict";

        return new Modelizer(resourceName, null, true, modelizeMetaResolver.asModelized(this), options);
      }

Other notes:

a) I am using the "promise" style, not using $future b) When doing a fetch instead, the "list" as seen in the JSON was accessible and I could extract all the response data. Of interest is that the resulting object when doing query is an Array of zero length.

VasilioRuzanni commented 9 years ago

@DoctorEJB I think I see what is your issue.

By calling modelize('receiptSummaryList').query({ ... }) you are effectively trying to fetch a collection of receiptSummaryList's (not a collection of receiptSummary). But it seems that receiptSummaryList is there to represent a collection of receiptSummary objects.

So, you can try using modelize.one(...).get(...) instead like this:

modelize.one('receiptSummaryList').get({ ... }).then(function (receiptSummary) {
  ...
});

This way it is fetched as a model and not collection. And since you have the list as a model attribute - it will be automatically set on teh model after successful Model.get(...) and/or modelInstance.fetch(...).


Just out of curiousity - is there any particular reason to have receiptSummaryList as a separate model and not use the receiptSummary model collection instead?

Just like this:

// Define the model
modelize.defineModel("receiptSummary", {
  baseUrl: '/the-client/service/purchaseOrder',

  receiptNumber: '',
  receiptDateTime: '',
  reversed: '',
  canadianPurchaseOrderValue: '',
  paymentTypeReferenceNumber: '',

  collection: {
    parse: function (responseData, options) {
      // The collection .parse() method should return the array of collection items
      return responseData.list;
    }
  }
});

// Then fetch the data as a collection
// Expects the object with the array under "list" key
modelize('receiptSummary').query({ ... }).then(function (receiptSummary) {
  ...
});
DoctorEJB commented 9 years ago

Thanks - our back end uses a wrapper pattern which generates the "list" object; so our modelizer model mirrors that pattern. I'm not sure if I can remove the ReceiptSummaryList object - I would have to test. I wanted to use .query() because we are generating dynamic URL query parameters.
Does modelizer support query parameters only for .query() or are they also supported for get and fetch?

VasilioRuzanni commented 9 years ago

@DoctorEJB Sure, they all use $request property internally, so all the params are passed to it. The Model.get() is just a shortcut for var something = new Model() and something.fetch() (with all params passed.

DoctorEJB commented 9 years ago

FYI - I have coded a workaround whereby I build the query part of the URL and append it to the baseUrl of the model object. Works ok but its a bit of a hack. Longer term we may revisit the wrapper pattern. Thanks for your help Vasilio - you pinpointed the crux of the problem right away!

VasilioRuzanni commented 9 years ago

@DoctorEJB FYI, you can append the query-string params via fetch like this (its just the way Angular $http service works with params, nothing new here really):

var model = modelize('receiptSummary').$new();
var filterParams = {
  currencyCode: 'CAD',
  paymentTypeId: 12
};

// reset: true is optional - for the cases when you want to replace the entire collection with whatever comes from the server
model.fetch({ params: filterParams, reset: true });

// you could optionally provide a custom URL to be used instead of defined baseUrl:
model.fetch({ url: '/some/other/url', params: filterParams, reset: true });
VasilioRuzanni commented 9 years ago

@DoctorEJB No problem! Let me know if you need any help - will be glad to. If your issue is resolved - let me know either so that I can close this issue.

DoctorEJB commented 9 years ago

Ya let's close this - thanks again! Nice framework!

\DoctorEJB