Find json item based on other item in node.js - javascript

{
id: 23323091,
userId: 1743514,
teamId: 1693131,
name: 'test1'
},
{
id: 2332950,
userId: 1743514,
teamId: 1693131,
name: 'test2'
},
{
id: 23323850,
userId: 1743514,
teamId: 1693131,
name: 'test3'
}
Im trying find solution how to parse json result returned from GET request in node.js.
So I want find in json array with ex. name: 'test3' return id:
Here is full code:
const axios = require('axios');
let token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTc0MzUxNCwidXNlcm5hbWUiOiJzbmFwa2l0cmljaEBnbWFpbC5jb20iLCJyb2xlIjoiYWRtaW4iLCJ0ZWFtSWQiOjE2OTMxMzEsInRv';
axios.get('https://dolphin-anty-api.com/browser_profiles', {
headers: {
Authorization: `Bearer ${token}`
}
})
.then(function (response) {
const data = response.data;
console.log(data);
})
.catch(function (error) {
console.log(error);
});
and here is full data response from console log https://pastebin.com/wY0RVsUv

You can use the Array#find method
const elements = [
{
id: 23323091,
userId: 1743514,
teamId: 1693131,
name: 'test1'
},
{
id: 2332950,
userId: 1743514,
teamId: 1693131,
name: 'test2'
},
{
id: 23323850,
userId: 1743514,
teamId: 1693131,
name: 'test3'
}
]
function search(name) {
return elements.find(elem => elem.name == name)?.id
}
console.log(search('test3'))
console.log(search('test4'))

If you are inside a GET request, to return a Json just do response.json()
Store your JSON inside a const for example
const data = myParsedJsonObject
You can find whatever data you looking for using the ES6 find() method.
const names = data.find(el => el.name === "test3")

Related

How to from array want to form a pattern to make a query to make API call

I want to derive a pattern from an array. The Array could be n number of elements
This is the Array pattern I receive from DB, (Note here elements could be n numbers)
[
{ id: '2', name: 'ONe' },
{ id: '3', name: 'Twop' },
{ id: '1', name: 'ThreeC' }
]
And I want to for a patter like AccountId=2&AccountId=3&AccountId=1 formed from the array and id in it
And I want to pass that formed data into the below URL as a query parameter to make an API call.
const config = {
method: 'get',
url: `${URL}api/cost?AccountId=1&AccountId=2&AccountId=3`,
headers: {
'Cookie': 'ARRAffinity=6f6eb54d3b6d7ed13173b9203b0bd6571b611d626818fba77a815805a7c90146'
},
data: data
};
const dataOutput = await axios(config )
.then(function (response) {
console.log(JSON.stringify(response.data));
return response.data;
})
.catch(function (error) {
console.log(error);
});
You can do it like this:
stackOverflow = () => {
let requestPartStr = '';
const data = [
{ id: '2', name: 'ONe' },
{ id: '3', name: 'Twop' },
{ id: '1', name: 'ThreeC' }
];
data.forEach((val, index) => {
requestPartStr += index !== data.length - 1
? `AccountId=${val.id}&`
: `AccountId=${val.id}`;
})
return requestPartStr;
};
Based on given code this can be a full code example:
const data = [
{ id: '2', name: 'ONe' },
{ id: '3', name: 'Twop' },
{ id: '1', name: 'ThreeC' }
];
getRequestParameters = (data) => {
let requestPartStr = '';
data.forEach((val, index) => {
requestPartStr += index !== data.length - 1
? `AccountId=${val.id}&`
: `AccountId=${val.id}`;
})
return requestPartStr;
};
const requestParameters = getRequestParameters(data);
const config = {
method: 'get',
url: `${URL}api/cost?${requestParameters}`,
headers: {
'Cookie': 'ARRAffinity=6f6eb54d3b6d7ed13173b9203b0bd6571b611d626818fba77a815805a7c90146'
},
data: data
};
const dataOutput = await axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
return response.data;
})
.catch(function (error) {
console.log(error);
});
Use map and join to build a params string
const data = [
{ id: "2", name: "ONe" },
{ id: "3", name: "Twop" },
{ id: "1", name: "ThreeC" },
];
const params = data.map(({ id }) => `AccountId=${id}`).join("&");
const url = `foo.com/api/cost?${params}`;
console.log(url);

Why async.map returns multiple copies of array?

const async = require('async');
const arr = [
{ name: 'john', id: '1' },
{ name: 'Andrie', id: '2' }]
let collectArr = [];
let data = async.mapLimit(arr, 5, async function (input) {
collectArr.push({ name: input.name, id: input.id });
return collectArr;
})
data.then((result) =>{
console.log('success',result);
}).catch(e => console.log('err'));
So here i am providing array to async.mapLimit without callback and expecting promise here.
Expected Output :- [ { name: 'john', id: '1' }, { name: 'Andrie', id: '2' } ] ,
Got Result :-
[ [ { name: 'john', id: '1' }, { name: 'Andrie', id: '2' } ],
[ { name: 'john', id: '1' }, { name: 'Andrie', id: '2' } ] ]
So my question is why it is creating multiple copies of array, how to deal with this?
You are needlessly returning a sub array, and the same array reference each iteration, when all you want is to return the new object.
let data = async.mapLimit(arr, 5, async function (input) {
return { name: input.name, id: input.id };
});
Not sure why you need this to be async

Transform an array of data by status

I need to filter an array by property:
Here's the data, which I get from the server:
const mockResults = [
{
user: {
firstName: '1',
lastName: '1'
},
status: 'WRONG'
},
{
user: {
firstName: '2',
lastName: '2'
},
status: 'WRONG'
},
{
user: {
firstName: '3',
lastName: '3'
},
status: 'CORRECT'
}
];
To display the data, I need to transform it to a required by ReactNative SectionList format:
const requiredFormat = [
{
status: 'WRONG',
data: [{ user: {firstName: '1', lastName: '1'}}, { user: {firstName: '2', lastName: '2'}}],
},
{
status: 'CORRECT',
data: [{ user: {firstName: '3', lastName: '3'}}],
},
];
Basically, the mockResults should be sorted by status. There can be maximum of 4 statuses: correct, wrong, missed, chosen. All these statuses should include all the data marked with them.
What is the right way to implement this?
I've tried to filter the array, but I'm stuck at this point:
const transformArray = mockResults.filter(item => {
return {
answerStatus: item.status,
data: [item.user]
}
})
You may walk through the array (using Array.prototype.reduce() method) and create new element of resulting array once you see there's no such with current status or append current element data if one exists:
const mockResults = [{user:{firstName:'1',lastName:'1'},status:'WRONG'},{user:{firstName:'2',lastName:'2'},status:'WRONG'},{user:{firstName:'3',lastName:'3'},status:'CORRECT'}],
result = mockResults.reduce((r,{status, ...rest}) => {
const common = r.find(e => e.status == status)
common ?
common.data.push(rest) :
r.push({status, data:[rest]})
return r
}, [])
console.log(result)
.as-console-wrapper {min-height:100%}
You can use reduce() to achieve that:
const mockResults = [{user: { firstName: '1', lastName: '1'}, status: 'WRONG'},{user: {firstName: '2',lastName: '2'},status: 'WRONG'},{user: { firstName: '3',lastName: '3'},status: 'CORRECT'}];
const result = mockResults.reduce((a, {user, status}) => {
const temp = a.find(e => e.status === status);
if (temp) {
temp.data.push({user});
} else {
a.push({status, data: [{user}]});
}
return a;
}, []);
console.log(result);
Read from the Array.prototype.reduce() documentation:
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.
I hope that helps!
You can reduce the array onto an object with its keys being the status property and its value an array of users with that status. Then, map over the entries to turn it back into an array of objects.
Note: The reduce function is creating a new object (accumulator) at each index. This is probably not practical for large data sets as it would be really slow.
const toSectionList = results =>
Object.entries(
results.reduce(
(obj, { user, status }) => ({
...obj,
[status]: [...(obj[status] || []), { user }],
}),
{}
)
).map(([status, data]) => ({ status, data }))
// example use:
const requiredFormat = toSectionList(mockResults)
The reduce function in this one modifies the accumulator object instead of creating a new one. It should preform better with larger data sets.
const toSectionList = results =>
Object.entries(
results.reduce((obj, { user, status }) => {
obj[status] = obj[status] || []
obj[status].push({ user })
return obj
}, {})
).map(([status, data]) => ({ status, data }))
That's what I did.
const mockResults = [
{
user: {
firstName: '1',
lastName: '1'
},
status: 'WRONG'
},
{
user: {
firstName: '2',
lastName: '2'
},
status: 'WRONG'
},
{
user: {
firstName: '3',
lastName: '3'
},
status: 'CORRECT'
}
]
function format(data) {
const resultDict = {}
for (let i of data) {
if (!resultDict[i.status]) {
resultDict[i.status] = { data: [] }
}
resultDict[i.status].data.push(i)
delete resultDict[i.status].data[resultDict[i.status].data.length - 1].status
}
const result = []
for (let i in resultDict) {
const res = {
status: i,
data: resultDict[i].data
}
result.push(res)
}
return result
}
console.log(format(mockResults))

ES6 array of hashes return unique array of hashes [duplicate]

This question already has answers here:
Create array of unique objects by property
(17 answers)
Closed 3 years ago.
I have an object that looks like this:
const posts = [
{ id: 0, user: { id: 5564, name: 'john'} },
{ id: 1, user: { id: 5564, name: 'john'} },
{ id: 2, user: { id: 5560, name: 'jane'} }
]
I need an array of the unique user hashes like this:
[
{ id: 5564, name: 'john'},
{ id: 5560, name: 'jane'}
]
I'm able to retrieve all the users attributes from the posts array by doing:
const postUsers = posts.map(post => post.user)
which returns:
[
{ id: 5564, name: 'john'},
{ id: 5564, name: 'john'},
{ id: 5560, name: 'jane'}
]
where user john is listed twice
I've been able to get my desired result by doing:
const unique = {};
const uniqueUsers = [];
for(var i in postUsers){
if(typeof(unique[postUsers[i].id]) == "undefined"){
uniqueUsers.push(postUsers[i]);
}
unique[postUsers[i].id] = 0;
};
uniqueUsers
but there must be a cleaner way.
I've also been able to return the unique ids of all users by doing:
var ids = posts.map(post => post.user.id)
var uniqueIds = Array.from(new Set(ids)).sort();
which returns
[5564, 5560]
not sure if that helps. this article helped me a little https://medium.com/tomincode/removing-array-duplicates-in-es6-551721c7e53f
You could take a Map and get only the unique users.
const
posts = [{ id: 0, user: { id: 5564, name: 'john'} }, { id: 1, user: { id: 5564, name: 'john'} }, { id: 2, user: { id: 5560, name: 'jane'} }],
unique = Array.from(posts.reduce((m, { user }) => m.set(user.id, user), new Map).values());
console.log(unique);
If you don't mind using lodash you can do something like
const users = _map.(posts, 'user') // To get the list of users
_.uniqBy(users, 'id') // to get the uniq ones
Put the objects directly in uniqueUsers, then use Object.values() at the end to convert the object to an array.
const posts = [
{ id: 0, user: { id: 5564, name: 'john'} },
{ id: 1, user: { id: 5564, name: 'john'} },
{ id: 2, user: { id: 5560, name: 'jane'} }
];
let uniqueUsers = {};
posts.forEach(({user}) => uniqueUsers[user.id] = user);
uniqueUsers = Object.values(uniqueUsers);
console.log(uniqueUsers);
Use reduce to reduce the array by checking if the value is already in the array. If it is already in the array, return the current state of the array, otherwise add the item to the array.
const posts = [
{ id: 0, user: { id: 5564, name: 'john'} },
{ id: 1, user: { id: 5564, name: 'john'} },
{ id: 2, user: { id: 5560, name: 'jane'} }
]
const r = posts.map(i => i.user).reduce((acc, itm) => {
return !acc.find(i => i.id == itm.id) && acc.concat(itm) || acc
}, [])
console.log(r)

map function save result to an object

this is what my response looks like
data: [
{
id: 3,
name: "Oliver Green",
email: "test#gmail.com",
contacts: "09179878564"
},
{
id: 2,
name: "Orval McLaughlin",
email: "okoch#example.org",
contacts: "09083692343",
}
]
I used the map function to get the user id and user name, now what I'm trying to do is to save all of the result to an Object
data(){
return {
autoComplete:{},
}
},
let vm = this;
response.data.data.map((user) =>
{
return vm.autoComplete = { [user.id] : user.name};
});
I get the result however I'm only getting one result
autoComplete:Object
2:"Orval McLaughlin"
the result should be
autoComplete:Object
3: "Oliver Green"
2: "Orval McLaughlin"
You need to return the object from map() not the result of an assignment. You are currently assigning vm.autoComplete on each iteration. After you do this you can assign the output of map to the variable you want:
let data = [
{
id: 3,
name: "Oliver Green",
email: "test#gmail.com",
contacts: "09179878564"
},
{
id: 2,
name: "Orval McLaughlin",
email: "okoch#example.org",
contacts: "09083692343",
}
]
let autoComplete = data.map((user) => {
return { [user.id] : user.name};
});
console.log(autoComplete)
EDIT:
If you want an object instead of an array, you should use reduce() because map() always returns an array:
let data = [
{
id: 3,
name: "Oliver Green",
email: "test#gmail.com",
contacts: "09179878564"
},
{
id: 2,
name: "Orval McLaughlin",
email: "okoch#example.org",
contacts: "09083692343",
}
]
let autoComplete = data.reduce((obj, user) =>{
obj[user.id] = user.name; // this assumes user.id will be unique
return obj
}, {});
console.log(autoComplete)
Try this for not wrapping it in array.
response.data.data.map((user) => {
return vm.autoComplete = Object.assign(vm.autoComplete, {[user.id] : user.name}); }
It seems the autoComplete be overwrite for each.
Maybe you can try these:
data(){
return {
autoComplete:{},
}
},
let vm = this;
vm.autoComplete = response.data.data.map((user) => {
return { [user.id] : user.name};
});

Categories

Resources