Ember.RSVP.hash在路由

时间:2017-05-03 22:12:22

标签: javascript asynchronous ember.js promise ember-data

编辑:进一步观察时,正在从模型钩子返回的数组上调用toString。硬编码,这种方法工作正常,但是像我下面那样返回它,它没有。

TL; DR:我正在将一个数据数组操作为不同的“格式”,以便我可以使用Ember Charts add。要做到这一点,我在我的路线的模型钩子中使用Ember.RSVP,但我得到TypeError: Cannot convert object to primitive value并且不知道为什么。

我一直在学习Ember(跟随他们的快速入门,然后是超级租赁教程),现在我正在尝试用它来构建我自己的项目。

我遇到的问题是在路由的模型钩子中处理异步操作。这可能是一个很长的阅读,但我试图非常具体。然而,最终的问题是,我在最后得到TypeError: Cannot convert object to primitive value

我正在使用Mirage假冒后端API,并返回我的数据:

    {
        "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
                }
            }
        ]
    };

我也在使用Addepar的Ember Charts(https://github.com/Addepar/ember-charts),这需要看起来像这样的数据(组标签是可选的,我没有将它用于我的应用程序,但这取自Addepar的文档) :

[{
    "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
}]

基本上,因为我遵循JSONAPI规范,我从API接收的数据看起来与需要传递到Ember Charts Vertical Bar Graph组件的数据不同。

到目前为止,我的解决方案(不起作用)是遍历初始数据并填充一个看起来像Ember Charts需要的新数组。据我所知,这只能异步发生,因为我必须进行API调用(好吧,调用我的商店),然后在从模型钩子返回新数组之前对结果进行操作。 / p>

这是我现在正在使用的实际代码:

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
        });
    }
});

这样就可以在我的模板中访问(该组件由Ember Charts插件提供){{vertical-bar-chart data=model.data}}

如开头所述,我得到TypeError: Cannot convert object to primitive value。我唯一的关键是它来自哪里,如果我硬编码数据(以第二种,正确的格式)并返回它而不是从幻影中拉出它,条形图就可以完美地填充。但如果我按照上面的方式进行,我就会收到错误。我使用了对console.log(resolvedModel)的afterModel钩子,并且数据有两种方式。也许这不是一个好的指标。

无论如何,我是Ember的超级绿色,我可能只是误解了所有这些东西。任何帮助表示赞赏。对不起,很长的帖子。

2 个答案:

答案 0 :(得分:0)

编辑:答案仍然在于JSON.parse(JSON.stringify(data)),但我更新了kumkanillam更简单的方法来返回数据。

事实证明,错误来自于从模型钩子返回的数据上调用Array.toString。它在硬编码的对象数组上运行良好,但在我通过RSVP返回时却没有。正如我在我的问题中所做的那样。

在检查两者时,事实证明,当使用Ember.RSVP时,返回数组中的对象在它们上缺少toString方法,不知何故......我尝试通过使用Object.create()设置原型来解决这个问题,但是没用。

底线是,我仍然不是100%清楚,我想也许Ember正在把我的数组变成别的东西(Ember对象?),而不仅仅是一个简单的JS对象数组。所以我最终通过this answer.

将返回的数据再次转换为普通的JS对象

路线现在看起来像这样:

    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));
    });
}

JSON.parse(JSON.stringify(data))基本上将数据转换为字符串,然后将其转换回JS对象。感觉有点脏,但是在做了同样的事情5个小时之后,这是唯一有用的东西!

答案 1 :(得分:0)

为什么需要RSVP.all和RSVP.hash?我遗漏了你的要求。 也许你可以给下面的代码一次尝试,

..
├── install.xml
└── upload
    ├── admin
    ├── catalog
    ├── composer.json 
    ├── image
    └── vendor

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

那样访问它