简体   繁体   English

Javascript对象到数组,长度= 0

[英]Javascript object to array, length = 0

I'm building a webshop where users are able to add products for one of more stores in their basket and checkout (like AliExpress). 我正在建立一个网上商店,用户可以在其商店的购物篮和结帐处添加更多商店之一的产品(例如AliExpress)。

On the cart overview page, the content of the basket is shown sorted by store. 在购物车总览页面上,按商店分类显示了购物篮的内容。 If the same product is added multiple times over different stores, the product is show by every store. 如果同一商品在不同的商店中多次添加,则该商品将在每个商店中显示。

Now, I want to create an order for every store with the products ordered by that store. 现在,我想使用该商店订购的产品为每个商店创建一个订单。 I'm using Angular to create the list with products ordered/filtered by store. 我正在使用Angular创建按商店订购/筛选的产品的列表。 That data will be sent to my Node.JS server, to loop the contents and create some orders with items. 该数据将被发送到我的Node.JS服务器,以循环内容并创建一些带有项目的订单。
The problem, I think, is that the data is processed like a 'object' and not an 'array'. 我认为,问题在于数据的处理方式像“对象”而不是“数组”。 I have found a function which converts a object to an array, but the length is still '0'. 我发现了一个将对象转换为数组的函数,但是长度仍然为'0'。

How can I process the data so I can loop through the different items? 如何处理数据,以便可以遍历不同的项目?

AngularJS code to sort cart by store AngularJS代码按商店对购物车进行排序

$scope.filterProducts = function(groupName) {
    $scope.productList = [];
    $http({
      method: 'GET',
      xhrFields: {withCredentials: true},
      url: '/loadCart'
    }).then(function successCallback(response){
        if (response.data) {
            var mapByShop = function(arr, groupName) {
                return arr.reduce(function(result, item) {
                    result[item[groupName]] = result[item[groupName]] || {};
                    result[item[groupName]][item['productId']] = item;
                    console.log('GROUPNAME en RESULT', groupName, result);
                    return result;
                }, {});
            };
            if (response.data.length > 0) {
                if (groupName == 'shopName') {
                    $scope.productList = mapByShop(response.data, groupName);
                } else {
                    $scope.checkoutList = mapByShop(response.data, groupName);
                }
            }
        }
    }, function errorCallback(response){
        console.log(response);
    });
  }

The $scope.productList is sent as 'data' in a $http POST function. $scope.productList$http POST函数中作为“数据”发送。

Node.JS code to convert an object to an array Node.JS代码将对象转换为数组

function convertObjectToArray(object, cb){
    var cartContent = [];
    for (var i in object) {
        cartContent[i] = object[i];
    }
    console.log("convertObjectToArray");

    return cb(cartContent);
}

Code to process the data (where length is zero) 处理数据的代码(长度为零)

convertObjectToArray(req.body.cart, function(result){
    console.log(isArray(result));
    console.log('result', result);
    console.log("lenght", result.length);
})

FYI: the isArray function 仅供参考: isArray函数

function isArray(myArray) {
    return myArray.constructor.toString().indexOf("Array") > -1;
}

if array order is not important, you should use 如果数组顺序不重要,则应使用

cartContent.push(object[i]);

It will update the .length property automaticly 它将自动更新.length属性

Your problem is that you are adding properties to the array object, and not using the Array API to insert at integer locations in the object. 您的问题是您要向数组对象添加属性,而不是使用数组API在对象的整数位置插入。 This means the array essentially remains "empty". 这意味着该数组基本上保持为“空”。 If you key on an integer when inserting into the array then your code will work better. 如果在插入数组时键入整数,则代码将更好地工作。

The broken bit: 断点:

for (var i in object) {
    cartContent[i] = object[i];
}

i is a string key here and will not increment the length of the Array unless the value coerces to an integer value (I think). i在这里是一个字符串键,除非该值强制转换为整数值(我认为),否则不会增加Array的长度。

Something like this might work: 这样的事情可能会起作用:

// Untested...
var keys = Object.keys(object);
for (var i = 0; i < keys.length; i++) {
    cartContent[i] = object[keys[i]];
}

Or like the other answer suggested, use the push API. 或像建议的其他答案一样,使用push API。

Aside: 在旁边:

If you are in a modern JS engine you can: 如果您使用的是现代JS引擎,则可以:

  1. Use Object.values , or 使用Object.values ,或

  2. Write a couple of utility functions and convert an object to an array using the following 编写一些实用程序函数,然后使用以下命令将对象转换为数组

:

var o = iterable({foo:'fooValue', bar: 'barValue'});
console.log([...o]);

The utility functions: 实用程序功能:

function iterable(o) {
    if(o[Symbol.iterator]) {
        return o;
    }

    o[Symbol.iterator] = iter.bind(null, o);
    return o;
}

function* iter(o) {
    var keys = Object.keys(o);
    for (var i=0; i<keys.length; i++) {
        yield o[keys[i]];
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM