I'm trying to post data from Axios to my API but although my json data looks correct when passing to Axios, browser tools tells me that my nested property is empty.
My data contains nested objects and looks like this:
{
'name': 'foo',
'index': 1,
'nested': [
{
'date': '2020-05-10',
'geojson_data': {
'crs': Object,
'name': 'my-name',
'type': 'FeatureCollection',
'features': [{ ... }, { ... }]
}
},
]
}
Edit: geojson_data results from parsing .geojson file, thus, the features array contains ~300 items.
My axios function is defined here:
async post(data) {
console.log(data);
return axios
.post(API_URL + 'endpoint/',
data,
{
headers: authHeader()
})
.then(response => {
return response.data;
})
}
authHeader() is used to provide Bearer token authorization.
I check that data passed to axios is correct (looks like above), but browser tools tell me that data actually sent looks like
{"name":"foo","index":1,"nested":[]}
Why is my array empty ?
Edit: I tried to manually populate a sample nested object and it seems to work. Yet, whenever I use my actual data, it doesn't.
Don't know if it's relevant but in the console, here is the difference I can see between the 2 collapsed objects (actual vs sample):
Sample : Object { name: "foo", index: "1", nested: (1) […] }
Actual : Object { name: "foo", index: "1", nested: [] }
Notice the nested array which looks like it is empty. Yet, if I expand it, they look the same. Any ideas ?
P.S: looks like this SO post from 3 years ago, but without solution
Related
Here is my response I get from API request:
[ 'bookShelf3', 'bookShelf4', 'bookShelf5' ]
Here is a part of my code which searches through my mongoDB Databese:
const responseToSearchC = (req, res) => {
console.log(req.body.searchTerm);
db.collection('subtitle')
.find({
series: { $in: ['bookShelf1'] },
$text: { $search: req.body.searchTerm },
})
I just want to make my code dynamic and instead hard coding ['bookShelf1']
set its value by JSON response.
the problem is the response from API is an object (although it is look like an array) and I cannot replace it with my hard codded array ['bookShelf1']
I tried to stringify it but it didn't work cuz its a string again, and not an array like hardcoded one
If the response is really an object like:
{ 0: 'bookShelf3', 1:'bookShelf4', 2: 'bookShelf5'}
you can simply utilize the Object.values() method which returns all of the object's values as an array.
Here's an example:
let ob={ 0: 'bookShelf3', 1:'bookShelf4', 2: 'bookShelf5'};
console.log(Object.values(ob));
I'm having some trouble passing into a variable that holds a json object into sendgrid's dynamic_template_data. My setup looks like this:
const send = async (address, mentions) => {
console.log('mentions json obj', mentions)
let name = "john"
try {
let config = {
headers: {
Authorization: `Bearer ${process.env.sendgridKey}`,
}
}
let data = {
personalizations: [
{
to: [
{
email: `${address}`,
},
],
dynamic_template_data: {
name: name,
allMentions: mentions
}
}
],
from: {
email: "email#email.com",
name: "Mentionscrawler Team"
},
template_id: process.env.template_id,
}
await axios.post("https://api.sendgrid.com/v3/mail/send", data, config)
} catch (error) {
console.error(error, 'failing here>>>>>>>')
}
}
when I console.log mentions, which is json, and paste the code I get from the terminal directly into the allMentions key, it works. but when I just pass in mentions itself, nothing shows up on the sent email. I've been very confused the last few hours why this is happening. Any advice appreciated.
edit: i should also note that allmentions is an object with keys that hold arrays. So I'm looking to iterate over those arrays. Again, this totally all works if I just paste in directly what mentions is, but passing in mentions is giving me an issue.
Thank you very much,
just realized what was wrong. sendgrid's template requires a json object, so I assumed that I needed to use json.stringify on my mentions obj. Turns out I didn't need to do that, as long as all values are in string format.
I have this code to get some stock data with deep nested associations by using nested-pop:
Stock.find({limit:100, sort:'name ASC'})
.populate('scans', {limit:1,sort:'createdAt DESC'})
.then((stocks) => {
return nestedPop(stocks, {
scans: ['values']
})
}).then(stocks => {
console.log(stocks[0].scans[0]);
res.json(stocks);
})
In the server console the scan is logged and the values array is printed. But res.json returns the stocks with scans that are all missing the values array.
Expected output:
[{
id: 1,
scans: [
{
id: 1,
values: [
{
id: 1,
value: 0.5,
type: 1
},
...
]
}
]
}, ...]
The returned output:
[{
id: 1,
scans: [
{
id: 1,
}
]
}, ...]
The error doesn't seem to be related to the depth of the object, because I tested it with some deeper test object and everything was returned. I just don't understand how this is not returned by res.json if it's there.
UPDATE:
I made other tests now and found out that both, .toObject and .toJSON called on a single stock cause the values to disappear on the server side. And because res.json is calling .toJSON on the passed objects it also doesn't appear in the browser.
nestedPop is returning values that can not be parsed correctly by .toJSON, because they are already converted.
I solved the problem by converting all stocks before I pass them into nestedPop, so the working code is:
Stock.find({limit:100, sort:'name ASC'})
.populate('scans', {limit:1,sort:'createdAt DESC'})
.then((stocks) => {
stocks = stocks.map((s) => s.toJSON());
return nestedPop(stocks, {
scans: ['values']
})
}).then(stocks => {
console.log(stocks[0].scans[0]);
res.json(stocks);
})
Now everything is logged on the server side AND passed to browser.
Say I have a collection that gets automatically returned in my app when I call a function, and it turns out something like this:
Collection {
'1234567890' => Message {
channel: TextChannel {
type: 'text',
id: '362557066864230402'
},
type: "DEFAULT",
content: "test"
}
}
I'm unsure about the '1234567890' => Message part. I understand that it's ES6, but I don't know how to call any of the nested data inside of it, such as content: "test".
To get to that (assuming the collection is using the variable collection, I've tried:
let data = collection["123567890"].content;
let data2 = collection[0].content; //I know that's for arrays, but I thought it would be similar
Both output 'null' or undefined, with the error
TypeError: Cannot read property 'content' of undefined
So I understand that I cannot get the initial collection object.
One last thing: That number 1234567890 is randomly generated each time the function is called, so I cannot hardcode anything easily.
Pastebin to the actual collection example.
For some reason, it stops printing after that line (possibly too many characters?)
EDIT: My code:
msg.channel.awaitMessages(msg => msg.author==user, { time: 10000, max: 1, errors: ['time'] })
.then((collected) => {
let channel = collected[0];
console.log(collected);
console.log(JSON.stringify(collected));
if(channel=="cancel") {
msg.channel.send("cancel");
return;
}
})
.catch(() => {
// ect ect
});
Sorry that there isn't much clarification, this is really stumping me.
Why does this return a 400 error (Unique query may have at most one result. Got 100):
[{
name:null,
type:'music/artist'
}]
I'd expect it to return the first 100 names from music/artist? How is it a unique query?
I'm trying to build a random query, where I can provide two params - the page and the result from within the page to return - and get one item back
Would be awesome if MQL supported something like return: 'random'
EDIT - adds full Angular factory. The query runs fine if I punch it in to the freebase.com/query engine.
myApp.factory('FB_Random', function ($http) {
return {
fn: function (callback) {
$http.get("https://www.googleapis.com/freebase/v1/mqlread",
{
params: {
query:[{
name: null,
type: '/music/artist'
}]
}
}
).success(function (d, status, headers, config) {
callback(d.result);
}).error(function (d, status, headers, config) {
console.log(d);
});
}
};
});
Looks like there's some undocumented Angular behavior going on here. According to the Angular docs, the params parameter takes a "Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url."
However, it seems like there's some additional logic that looks for array values in the params map and turns them into repeated parameters; ie. ?query={...}&query={...}. Since your query is (properly) wrapped in array notation, indicating that you're expecting multiple results, Angular interprets it as a list with a single value for the query parameter. It then extracts that query parameter and adds it to the url like so:
https://www.googleapis.com/freebase/v1/mqlread?query={%22name%22:null,%22type%22:%22/music/artist%22}
This is why you get the error about your query incorrectly asking for a single result. Because Angular removed the outer array notation that's needed by MQL.
The simplest way to work around this is to simply wrap your query in an additional array like this:
$http.get("https://www.googleapis.com/freebase/v1/mqlread",
{
params: {
query:[[{
name: null,
type: '/music/artist'
}]]
}
}
)
If you'd like to make the fix more explicit and your code easier to read you can just stringify the MQL query yourself like this:
$http.get("https://www.googleapis.com/freebase/v1/mqlread",
{
params: {
query: JSON.stringify([{
name: null,
type: '/music/artist'
}])
}
}
)