Ember.RSVP.hash 在路由的模型钩子中给出 'cannot convert object to primitive value'

Ember.RSVP.hash gives 'cannot convert object to primitive value' in model hook of route

编辑:进一步观察,某些东西正在从模型挂钩 returned 数组上调用 toString。硬编码,此方法工作正常,但像我下面那样被 returned,它没有。

TL;DR:我正在将一组数据处理成不同的 "format",这样我就可以使用 Ember 图表插件。为此,我在路线的模型挂钩中使用了 Ember.RSVP,但我得到了 TypeError: Cannot convert object to primitive value 并且不知道为什么。

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

我遇到的问题是在我的路由模型挂钩中处理异步操作。这可能是一篇很长的文章,但我试图非常具体。然而,最终的问题是我在这一切结束时得到了一个 TypeError: Cannot convert object to primitive value

我正在使用 Mirage 伪造后端 API,它 return 我的数据是这样的:

    {
        "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 (https://github.com/Addepar/ember-charts) 的 Ember 图表,它需要看起来像这样的数据(组标签是可选的,我没有将它用于我的应用程序,但是这个取自 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 图表垂直条形图组件。

我目前的解决方案(无效)是遍历初始数据并填充一个看起来像 Ember Charts 需要它的方式的新数组。据我所知,这只能异步发生,因为我必须进行 API 调用(好吧,调用我的商店),然后对 returning 之前获得的结果进行操作来自模型挂钩的新数组。

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

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 图表插件提供){{vertical-bar-chart data=model.data}}

如开头所述,我得到 TypeError: Cannot convert object to primitive value。我唯一知道它来自哪里的事实是,如果我对数据进行硬编码(以第二种正确的格式)并 return 它而不是从 Mirage 中提取它,则条形图可以很好地填充。但是,如果我按照上面的方式进行操作,则会出现错误。我使用 afterModel 挂钩到 console.log(resolvedModel),无论哪种方式,数据都在那里。也许这不是一个好的指标。

无论如何,我对 Ember 非常陌生,我可能只是因为误解了所有这些东西而受苦。任何帮助表示赞赏。很抱歉 post.

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

事实证明,错误来自 Array.toString 对从模型挂钩返回的数据进行调用。它在硬编码的对象数组上运行良好,但在我的问题中通过 RSVP 返回时却不行。

检查两者后,结果发现,当使用 Ember.RSVP 时,返回数组中的对象缺少 toString 方法,不知何故...我尝试通过使用 [=28 设置原型来解决这个问题=](),但没用。

底线是,我仍然不是 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 个小时后,这是唯一有效的方法!

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

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

和模板,您需要像 model

一样访问它