2017-05-03 2 views
0

EDIT: Bei weiterem Aufruf, ruft etwas toString auf das Array vom Modell Hook zurückgegeben wird. Hart-codiert, funktioniert diese Methode gut, aber zurückgegeben wird, wie ich unten habe, tut es nicht.Ember.RSVP.hash gibt 'kann Objekt in primitiven Wert nicht konvertieren' in Modell Hook der Route

TL; DR: Ich manipuliere ein Array von Daten in ein anderes "Format", so dass ich die Ember Charts hinzufügen kann. Um dies zu tun, verwende ich Ember.RSVP in der Modell-Hook meiner Route, aber ich bekomme eine TypeError: Cannot convert object to primitive value und weiß nicht warum.

Ich habe Ember gelernt (gefolgt von ihrem Schnellstart und dann Super-Vermietung Tutorial), und ich versuche jetzt, mein eigenes Projekt damit zu bauen.

Das Problem, das ich habe, beschäftigt sich mit asynchronen Operationen innerhalb des Modellhakens meiner Route. Das mag lange dauern, aber ich versuche sehr genau zu sein. Das Ende Problem ist jedoch, dass ich am Ende von allem ein TypeError: Cannot convert object to primitive value bekomme.

Ich verwende Mirage zu fälschen einer Back-End-API, und es gibt meine Daten wie folgt aus:

{ 
     "data": [ 
      { 
       "id": "May, 2017", 
       "type": "month", 
       "attributes": { 
        "label": "05/2017", 
        "value": 6 
       } 
      }, { 
       "id": "April, 2017", 
       "type": "month", 
       "attributes": { 
        "label": "04/2017", 
        "value": 5 
       } 
      }, { 
       "id": "March, 2017", 
       "type": "month", 
       "attributes": { 
        "label": "03/2017", 
        "value": 4 
       } 
      }, { 
       "id": "February, 2017", 
       "type": "month", 
       "attributes": { 
        "label": "02/2017", 
        "value": 3 
       } 
      }, { 
       "id": "January, 2017", 
       "type": "month", 
       "attributes": { 
        "label": "01/2017", 
        "value": 2 
       } 
      }, { 
       "id": "December, 2016", 
       "type": "month", 
       "attributes": { 
        "label": "12/2016", 
        "value": 1 
       } 
      } 
     ] 
    }; 

Ich verwende auch Charts Ember aus Addepar (https://github.com/Addepar/ember-charts), die Daten benötigt, die wie folgt aussieht (Gruppen-Label ist optional und ich verwende es nicht für meine app, aber dies wird von Addepar der docs genommen):

[{ 
    "label": "Label 1", 
    "group": "Group One", 
    "value": 20 
}, 
{ 
    "label": "Label 2", 
    "group": "Group One", 
    "value": 22 
}, 
{ 
    "label": "Label 3", 
    "group": "Group One", 
    "value": 18 
}, 
{ 
    "label": "Label 4", 
    "group": "Group One", 
    "value": 2 
}, 
{ 
    "label": "Label 5", 
    "group": "Group One", 
    "value": 6 
}, 
{ 
    "label": "Label 1", 
    "group": "Group Two", 
    "value": 26 
}, 
{ 
    "label": "Label 2", 
    "group": "Group Two", 
    "value": 18 
}, 
{ 
    "label": "Label 3", 
    "group": "Group Two", 
    "value": 150 
}, 
{ 
    "label": "Label 4", 
    "group": "Group Two", 
    "value": 160 
}, 
{ 
    "label": "Label 5", 
    "group": "Group Two", 
    "value": 200 
}, 
{ 
    "label": "Label 1", 
    "group": "Group Three", 
    "value": 14 
}, 
{ 
    "label": "Label 2", 
    "group": "Group Three", 
    "value": 31 
}, 
{ 
    "label": "Label 3", 
    "group": "Group Three", 
    "value": 44 
}, 
{ 
    "label": "Label 4", 
    "group": "Group Three", 
    "value": 30 
}, 
{ 
    "label": "Label 5", 
    "group": "Group Three", 
    "value": 62 
}, 
{ 
    "label": "Label 1", 
    "group": "Group Four", 
    "value": 75 
}, 
{ 
    "label": "Label 2", 
    "group": "Group Four", 
    "value": 114 
}, 
{ 
    "label": "Label 3", 
    "group": "Group Four", 
    "value": 19 
}, 
{ 
    "label": "Label 4", 
    "group": "Group Four", 
    "value": 129 
}, 
{ 
    "label": "Label 5", 
    "group": "Group Four", 
    "value": 52 
}, 
{ 
    "label": "Label 1", 
    "group": "Group Five", 
    "value": 200 
}, 
{ 
    "label": "Label 2", 
    "group": "Group Five", 
    "value": 14 
}, 
{ 
    "label": "Label 3", 
    "group": "Group Five", 
    "value": 31 
}, 
{ 
    "label": "Label 4", 
    "group": "Group Five", 
    "value": 44 
}, 
{ 
    "label": "Label 5", 
    "group": "Group Five", 
    "value": 30 
}] 

Grundsätzlich, weil ich die JSONAPI Spezifikationen folgende bin, die Daten ich erhalte von der Die API sieht anders aus als in den Ember Charts Vert ical Balkendiagramm-Komponente.

Meine bisherige Lösung (die nicht funktioniert) besteht darin, die Ausgangsdaten zu durchlaufen und ein neues Array zu füllen, das so aussieht, wie es Ember Charts benötigen. Soweit ich weiß, kann dies nur asynchron geschehen, weil ich einen API-Aufruf (na ja, einen Aufruf an meinen Speicher) machen muss und dann die Ergebnisse bearbeiten muss, die ich bekomme, bevor ich das neue Array vom Modell-Hook zurückgebe.

Hier ist der eigentliche Code, der ich jetzt bin mit:

import Ember from 'ember'; 

export default Ember.Route.extend({ 
    model() { 
     var results = this.get('store').findAll('month'); 

     var months = results.then(function(data) { 
      var monthsArray = []; 

      data.content.forEach(month => { 
       monthsArray.push(month.__data); 
      }); 

      return Ember.RSVP.all(monthsArray); 
     }); 

     return Ember.RSVP.hash({ 
      data: months 
     }); 
    } 
}); 

Dies wie dies in meinem Vorlage zugegriffen wird (die Komponente der Ember Charts Addon zur Verfügung gestellt) {{vertical-bar-chart data=model.data}}.

Wie am Anfang angegeben, bekomme ich eine TypeError: Cannot convert object to primitive value. Mein einziger Anhaltspunkt dafür, woher es kommt, ist die Tatsache, dass, wenn ich die Daten (im zweiten, korrekten Format) fest codiere und sie zurückgebe, anstatt sie aus Mirage zu ziehen, füllt sich das Balkendiagramm vollkommen gut. Aber wenn ich es so mache, wie ich oben habe, bekomme ich den Fehler. Ich habe den afterModel Hook zu console.log(resolvedModel) verwendet, und die Daten sind dort entweder vorhanden. Vielleicht ist das aber kein guter Indikator.

Wie auch immer, ich bin super grün mit Ember und ich kann leiden nur Missverständnis all dieser Sachen. Jede Hilfe wird geschätzt. Entschuldigung für die lange Post.

+0

Parameter für Ember.RSVP.all zugreifen müssen sollte ein Array von Versprechungen sein, u sind vorbei Ebene Objekt –

Antwort

0

BEARBEITEN: Die Antwort liegt immer noch mit , aber ich aktualisierte mit Cumanillam viel einfacher Ansatz die Daten zurück.

Es stellte sich heraus, dass der Fehler von Array.toString kam, der an den Daten aufgerufen wurde, die vom Modell-Hook zurückgegeben wurden. Es funktionierte gut auf einem hart-kodierten Array von Objekten, aber nicht, wenn über RSVP zurückgegeben, wie ich in meiner Frage habe.

Bei der Untersuchung von beiden, es stellte sich heraus, wenn Ember.RSVP, die Objekte in der zurückgegebenen Array fehlte eine toString-Methode auf sie irgendwie ... Ich habe versucht, dies zu lösen, indem Sie den Prototyp mit Object.create() aber hat nicht funktioniert.

Fazit ist, und ich bin immer noch nicht 100% klar, ich dachte, vielleicht Ember mein Array in etwas anderes (ein Ember-Objekt?), Nicht nur ein einfaches JS-Array von Objekten. So landete ich wieder die zurückgegebenen Daten in ein einfaches JS-Objekt konvertierte auf, über this answer.

Strecke sieht nun wie folgt aus:

model() { 
    // Fetch month data from store 
    return this.get('store').findAll('month').then(data => { 
     var monthsArray = []; 
     data.content.forEach(month => { 
      monthsArray.push(month.__data); 
     }); 

     // Must convert into normal JS object to avoid TypeError: cannot convert object into primitive value 
     return JSON.parse(JSON.stringify(monthsArray)); 
    }); 
} 

Die JSON.parse(JSON.stringify(data)) im Grunde dreht sich die Daten in einen String und wandelt sie dann wieder in eine JS-Objekt Es fühlt sich ein bisschen dreckig an, aber nach 5 Stunden Arbeit an der gleichen Sache ist es das einzige, was funktioniert hat!

0

Warum brauchen Sie RSVP.all und RSVP.hash?. Ich vermisse etwas von Ihrer Anforderung. Mai werden Sie den Code unten ein Versuch geben kann,

model() { 
     return this.get('store').findAll('month').then(data => { 
      var monthsArray = []; 
      data.content.forEach(month => { 
       monthsArray.push(month.__data); 
      }); 
      return monthsArray; 
     }); 
    } 

und temlate Sie es wie model

+1

Heilige raucht! Immer noch nicht das eigentliche Problem gelöst (die Konvertierung TypeError ... muss noch die JSON-Konvertierung in meiner Antwort tun), aber es hat eine Menge unnötigen Code aus dem, was ich tat, geschnitten. Ich übermäßig kompliziert das asynchrone Verhalten hier. –

Verwandte Themen