I'd need your help because I get the typeError mentionned in the question and I'm not sure to understand why. I've got an object (that es back from a request-promise) that looks like this:
{
"statusCode": 200,
"body": {
"BTC_USD": {
"buy_price": "4258",
"sell_price": "4265",
"last_trade": "4265",
"high": "4360",
"low": "4200",
"avg": "4260.2077946",
"vol": "219.32404491",
"vol_curr": "933982.49730504",
"updated": 1503767188
},
"BTC_EUR": {
"buy_price": "3640.1001",
"sell_price": "3650",
"last_trade": "3644.8",
"high": "3801.999999",
"low": "3622.000006",
"avg": "3685.0414084",
"vol": "94.48595035",
"vol_curr": "347993.56447153",
"updated": 1503767128
},
"BTC_RUB": {
"buy_price": "243511",
"sell_price": "244340",
"last_trade": "243511.49870226",
"high": "248786.99",
"low": "239630",
"avg": "243430.47675799",
"vol": "140.12303781",
"vol_curr": "34185015.26771479",
"updated": 1503767190
},
"BTC_UAH": {
"buy_price": "107000",
"sell_price": "107790",
"last_trade": "107790",
"high": "109900",
"low": "105354",
"avg": "108167.30195869",
"vol": "34.94251977",
"vol_curr": "3770330.73968614",
"updated": 1503767167
},
"DASH_BTC": {
"buy_price": "0.08528559",
"sell_price": "0.08644069",
"last_trade": "0.086196",
"high": "0.093364",
"low": "0.07043",
"avg": "0.0803689",
"vol": "1595.2753788",
"vol_curr": "123.76291968",
"updated": 1503767189
},
},
"request": {
"uri": {
"protocol": "https:",
"slashes": true,
"auth": null,
"host": "api.exmo",
"port": 443,
"hostname": "api.exmo",
"hash": null,
"search": null,
"query": null,
"pathname": "/v1/ticker/",
"path": "/v1/ticker/",
"href": "/"
},
"method": "GET",
"headers": {
"accept": "application/json"
}
}
}
as you can see, the body
has multiple objects and my goal is to rearrange the info in a new layout for each body.keys
:
Object.keys(res.body).forEach((k) => {
result= {
mk: 'exmo',
name: k,
a: res.body[k].sell_price,
b: res.body[k].buy_price,
c: res.body[k].last_trade,
v: res.body[k].vol,
t: res.body[k].vol_curr,
l: res.body[k].low,
h: res.body[k].high,
sn: res.body[k].updated,
}
});
return result;
But for some reason it's not working... I feel like I'm not using the Promise.all properly?
Here's my full code for testing (it reproduces the error):
function exmo() {
Promise.all(
function () {
var result = {};
var res = {
"statusCode": 200,
"body": {
"BTC_USD": {
"buy_price": "4258",
"sell_price": "4265",
"last_trade": "4265",
"high": "4360",
"low": "4200",
"avg": "4260.2077946",
"vol": "219.32404491",
"vol_curr": "933982.49730504",
"updated": 1503767188
},
"BTC_EUR": {
"buy_price": "3640.1001",
"sell_price": "3650",
"last_trade": "3644.8",
"high": "3801.999999",
"low": "3622.000006",
"avg": "3685.0414084",
"vol": "94.48595035",
"vol_curr": "347993.56447153",
"updated": 1503767128
},
"BTC_RUB": {
"buy_price": "243511",
"sell_price": "244340",
"last_trade": "243511.49870226",
"high": "248786.99",
"low": "239630",
"avg": "243430.47675799",
"vol": "140.12303781",
"vol_curr": "34185015.26771479",
"updated": 1503767190
},
"BTC_UAH": {
"buy_price": "107000",
"sell_price": "107790",
"last_trade": "107790",
"high": "109900",
"low": "105354",
"avg": "108167.30195869",
"vol": "34.94251977",
"vol_curr": "3770330.73968614",
"updated": 1503767167
},
"DASH_BTC": {
"buy_price": "0.08528559",
"sell_price": "0.08644069",
"last_trade": "0.086196",
"high": "0.093364",
"low": "0.07043",
"avg": "0.0803689",
"vol": "1595.2753788",
"vol_curr": "123.76291968",
"updated": 1503767189
},
},
"request": {
"uri": {
"protocol": "https:",
"slashes": true,
"auth": null,
"host": "api.exmo",
"port": 443,
"hostname": "api.exmo",
"hash": null,
"search": null,
"query": null,
"pathname": "/v1/ticker/",
"path": "/v1/ticker/",
"href": "/"
},
"method": "GET",
"headers": {
"accept": "application/json"
}
}
}
Object.keys(res.body).forEach((k) => {
result= {
mk: 'exmo',
name: k,
a: res.body[k].sell_price,
b: res.body[k].buy_price,
c: res.body[k].last_trade,
v: res.body[k].vol,
t: res.body[k].vol_curr,
l: res.body[k].low,
h: res.body[k].high,
sn: res.body[k].updated,
}
});
return result;
}).then((data) => {
console.log(JSON.stringify(data, null, 3));
})
};
exmo();
thanks in advance to you all for your help!
***** EDIT *****: [Trying to clarify] My objective was to get a single object per iteration of forEach. Ultimately each of these object would go into a mongo database. I'm using incorrectly Promise.all (because it needs an array of promises) but was looking for a similar solution.
I'd need your help because I get the typeError mentionned in the question and I'm not sure to understand why. I've got an object (that es back from a request-promise) that looks like this:
{
"statusCode": 200,
"body": {
"BTC_USD": {
"buy_price": "4258",
"sell_price": "4265",
"last_trade": "4265",
"high": "4360",
"low": "4200",
"avg": "4260.2077946",
"vol": "219.32404491",
"vol_curr": "933982.49730504",
"updated": 1503767188
},
"BTC_EUR": {
"buy_price": "3640.1001",
"sell_price": "3650",
"last_trade": "3644.8",
"high": "3801.999999",
"low": "3622.000006",
"avg": "3685.0414084",
"vol": "94.48595035",
"vol_curr": "347993.56447153",
"updated": 1503767128
},
"BTC_RUB": {
"buy_price": "243511",
"sell_price": "244340",
"last_trade": "243511.49870226",
"high": "248786.99",
"low": "239630",
"avg": "243430.47675799",
"vol": "140.12303781",
"vol_curr": "34185015.26771479",
"updated": 1503767190
},
"BTC_UAH": {
"buy_price": "107000",
"sell_price": "107790",
"last_trade": "107790",
"high": "109900",
"low": "105354",
"avg": "108167.30195869",
"vol": "34.94251977",
"vol_curr": "3770330.73968614",
"updated": 1503767167
},
"DASH_BTC": {
"buy_price": "0.08528559",
"sell_price": "0.08644069",
"last_trade": "0.086196",
"high": "0.093364",
"low": "0.07043",
"avg": "0.0803689",
"vol": "1595.2753788",
"vol_curr": "123.76291968",
"updated": 1503767189
},
},
"request": {
"uri": {
"protocol": "https:",
"slashes": true,
"auth": null,
"host": "api.exmo.",
"port": 443,
"hostname": "api.exmo.",
"hash": null,
"search": null,
"query": null,
"pathname": "/v1/ticker/",
"path": "/v1/ticker/",
"href": "https://api.exmo./v1/ticker/"
},
"method": "GET",
"headers": {
"accept": "application/json"
}
}
}
as you can see, the body
has multiple objects and my goal is to rearrange the info in a new layout for each body.keys
:
Object.keys(res.body).forEach((k) => {
result= {
mk: 'exmo',
name: k,
a: res.body[k].sell_price,
b: res.body[k].buy_price,
c: res.body[k].last_trade,
v: res.body[k].vol,
t: res.body[k].vol_curr,
l: res.body[k].low,
h: res.body[k].high,
sn: res.body[k].updated,
}
});
return result;
But for some reason it's not working... I feel like I'm not using the Promise.all properly?
Here's my full code for testing (it reproduces the error):
function exmo() {
Promise.all(
function () {
var result = {};
var res = {
"statusCode": 200,
"body": {
"BTC_USD": {
"buy_price": "4258",
"sell_price": "4265",
"last_trade": "4265",
"high": "4360",
"low": "4200",
"avg": "4260.2077946",
"vol": "219.32404491",
"vol_curr": "933982.49730504",
"updated": 1503767188
},
"BTC_EUR": {
"buy_price": "3640.1001",
"sell_price": "3650",
"last_trade": "3644.8",
"high": "3801.999999",
"low": "3622.000006",
"avg": "3685.0414084",
"vol": "94.48595035",
"vol_curr": "347993.56447153",
"updated": 1503767128
},
"BTC_RUB": {
"buy_price": "243511",
"sell_price": "244340",
"last_trade": "243511.49870226",
"high": "248786.99",
"low": "239630",
"avg": "243430.47675799",
"vol": "140.12303781",
"vol_curr": "34185015.26771479",
"updated": 1503767190
},
"BTC_UAH": {
"buy_price": "107000",
"sell_price": "107790",
"last_trade": "107790",
"high": "109900",
"low": "105354",
"avg": "108167.30195869",
"vol": "34.94251977",
"vol_curr": "3770330.73968614",
"updated": 1503767167
},
"DASH_BTC": {
"buy_price": "0.08528559",
"sell_price": "0.08644069",
"last_trade": "0.086196",
"high": "0.093364",
"low": "0.07043",
"avg": "0.0803689",
"vol": "1595.2753788",
"vol_curr": "123.76291968",
"updated": 1503767189
},
},
"request": {
"uri": {
"protocol": "https:",
"slashes": true,
"auth": null,
"host": "api.exmo.",
"port": 443,
"hostname": "api.exmo.",
"hash": null,
"search": null,
"query": null,
"pathname": "/v1/ticker/",
"path": "/v1/ticker/",
"href": "https://api.exmo./v1/ticker/"
},
"method": "GET",
"headers": {
"accept": "application/json"
}
}
}
Object.keys(res.body).forEach((k) => {
result= {
mk: 'exmo',
name: k,
a: res.body[k].sell_price,
b: res.body[k].buy_price,
c: res.body[k].last_trade,
v: res.body[k].vol,
t: res.body[k].vol_curr,
l: res.body[k].low,
h: res.body[k].high,
sn: res.body[k].updated,
}
});
return result;
}).then((data) => {
console.log(JSON.stringify(data, null, 3));
})
};
exmo();
thanks in advance to you all for your help!
***** EDIT *****: [Trying to clarify] My objective was to get a single object per iteration of forEach. Ultimately each of these object would go into a mongo database. I'm using incorrectly Promise.all (because it needs an array of promises) but was looking for a similar solution.
Share Improve this question edited Aug 26, 2017 at 19:41 Martin Carre asked Aug 26, 2017 at 17:57 Martin CarreMartin Carre 1,2494 gold badges23 silver badges45 bronze badges 8- 1 Please tell us what output you are trying to end up with. – jfriend00 Commented Aug 26, 2017 at 18:06
- 1 More than "needs to be rewritten" is "just remove some line of code", pastebin./raw/znLHzvz7 Is that what you want? – Federkun Commented Aug 26, 2017 at 18:09
-
3
Promise.all()
should be passed an array of promises. You are passing it a function which will never be called. For starters, remove thePromise.all()
entirely. – jfriend00 Commented Aug 26, 2017 at 18:10 -
Don't use
forEach
. Also what are you trying to do withresult
? – Bergi Commented Aug 26, 2017 at 18:16 - 2 Voting to close as this question is simply unclear and the OP is not around to clarify. – jfriend00 Commented Aug 26, 2017 at 18:41
3 Answers
Reset to default 3Your question is plicated a little by your code being all lumped in together, so here I've split it up.
This function mimics your server response as an example to show you how the promise can be managed.
function getData() {
return new Promise((resolve, reject) => {
// Parse the returned data
resolve(JSON.parse(res));
});
}
Then you need to transform your data. Here you can use map
to iterate over the obj instead of forEach
:
function mapData(obj) {
return Object.keys(obj.body).map((k) => {
return {
mk: 'exmo',
name: k,
a: res.body[k].sell_price,
b: res.body[k].buy_price,
c: res.body[k].last_trade,
v: res.body[k].vol,
t: res.body[k].vol_curr,
l: res.body[k].low,
h: res.body[k].high,
sn: res.body[k].updated
}
});
}
Then you can simply call getData
, mapData
, and then output the result. You don't want Promise.all
here because that method only accepts an array of promises.
getData()
.then(mapData)
.then(data => console.log(JSON.stringify(data, null, 3)));
DEMO (n.b. this demo uses your parsed obj so doesn't reparse it again in getData
).
As you can see, you're reassigning result
over and over in the sane loop forEach()
, the return
at the end could only return the information of the last key in body
.
What you need to do is to put all values with the same key in an array (maybe?).
Or in a simpler way: transpose the whole table.
Therefore, you gotta declare bunch of Array
's at the first place:
// init
let result = { };
let keys = ['buy_price', 'sell_price', /* etc. */];
keys.forEach(k => result[k] = []);
// gathering informations
Object.keys(res.body).forEach(name =>
Object.keys(res.body[name]).forEach(k => result[k].push(res.body[name][k]))
);
Now you can easily get your information by the index from result
.
If you want to index'em by their original names, you can firstly initialize
result
as a bunch ofObject
's, then use thename
instead of directlypush()
in the innerforEach()
.
Object.keys(res.body[name]).forEach(k => result[k][name] = res.body[name][k])
Which makes more sense on 'transposing' the whole table.
Promise.all(iterable) it take an iterable object such as an Array or String.
I modified your code, it's giving output. Note :- your code logic i did't not change, it give result as your logic.
function exmo() {
var data = (function () {
var result = {};
var res = {
"statusCode": 200,
"body": {
"BTC_USD": {
"buy_price": "4258",
"sell_price": "4265",
"last_trade": "4265",
"high": "4360",
"low": "4200",
"avg": "4260.2077946",
"vol": "219.32404491",
"vol_curr": "933982.49730504",
"updated": 1503767188
},
"BTC_EUR": {
"buy_price": "3640.1001",
"sell_price": "3650",
"last_trade": "3644.8",
"high": "3801.999999",
"low": "3622.000006",
"avg": "3685.0414084",
"vol": "94.48595035",
"vol_curr": "347993.56447153",
"updated": 1503767128
},
"BTC_RUB": {
"buy_price": "243511",
"sell_price": "244340",
"last_trade": "243511.49870226",
"high": "248786.99",
"low": "239630",
"avg": "243430.47675799",
"vol": "140.12303781",
"vol_curr": "34185015.26771479",
"updated": 1503767190
},
"BTC_UAH": {
"buy_price": "107000",
"sell_price": "107790",
"last_trade": "107790",
"high": "109900",
"low": "105354",
"avg": "108167.30195869",
"vol": "34.94251977",
"vol_curr": "3770330.73968614",
"updated": 1503767167
},
"DASH_BTC": {
"buy_price": "0.08528559",
"sell_price": "0.08644069",
"last_trade": "0.086196",
"high": "0.093364",
"low": "0.07043",
"avg": "0.0803689",
"vol": "1595.2753788",
"vol_curr": "123.76291968",
"updated": 1503767189
},
},
"request": {
"uri": {
"protocol": "https:",
"slashes": true,
"auth": null,
"host": "api.exmo.",
"port": 443,
"hostname": "api.exmo.",
"hash": null,
"search": null,
"query": null,
"pathname": "/v1/ticker/",
"path": "/v1/ticker/",
"href": "https://api.exmo./v1/ticker/"
},
"method": "GET",
"headers": {
"accept": "application/json"
}
}
}
Object.keys(res.body).forEach((k) => {
result= {
mk: 'exmo',
name: k,
a: res.body[k].sell_price,
b: res.body[k].buy_price,
c: res.body[k].last_trade,
v: res.body[k].vol,
t: res.body[k].vol_curr,
l: res.body[k].low,
h: res.body[k].high,
sn: res.body[k].updated,
}
});
return result;
});
Promise.all([data()]).then((data) => {
console.log(JSON.stringify(data, null, 3));
})
};
exmo();
<!-- begin snippet: js hide: false console: true babel: false -->