Change an object value inside a loop in JavaScript - javascript

I have an array of objects like this:
const data = [{
_id:"49847444033",
name:"yoko"
},{
_id:"49847433333",
name:"doira"
}]
I have to change each item name property to something like this :
...
{
_id:"49847433333",
name:{
en:"John"
}
}
My attempt is to loop object like following :
data.forEach((item) => {
item.name = {en:"john"}
console.log(item)
})
But this always console the original item and the name property value is not modified.

const newData = data.map(user => ({ _id: user._id, name: { en: user.name } }))

I created a library to express transformations like this very simply.
const { pipe, fork, get } = require('rubico')
const data =
[ { _id: '49847444033', name: 'yoko'}
, { _id: '49847433333', name: 'doira'}
]
const onData = pipe([
fork({
_id: get('_id'), // data => data._id
name: fork({ en: get('name') }), // data => ({ en: data.name })
}),
console.log,
])
data.map(onData) /*
{ _id: '49847444033', name: { en: 'yoko' } }
{ _id: '49847433333', name: { en: 'doira' } }
*/
I've commented the code above, but to really understand rubico and get started using it, I recommend you read the intuition and then the docs

try somthing like:
const newList = data.map(obj => {
return { _id: obj._id, name: { en: obj.name } }
});
and the newList list is your new data list so you can do it:
data = newList;
EDIT:
if you have more properties you can change the return line to:
return { ...obj, name: { en: obj.name } }
what will happen here, it will deploy all the object properties as they are, and modify the name property, unfortunately, every property you want to modify, you have to re-write it.

Related

Axios returns a nested array with single objects after using Promise.all

I am using axios and my goal is to execute a get request inside a map function. The following function accept an array of Id's. The first step was to create a simple get function that will be called inside the MAP function.
In the try catch block, I set the Promise.all() method.
// Get imaged exercices
export const getImagedExercices = async array => {
let getIds = async element => {
let array = await axios.get(`http://localhost:3000/api/get-exercice-by-id/${element}`);
let data = await array.data;
return data;
}
try {
const arrayEx = array.map(item => item.exerciceId);
let mappedResult = await Promise.all(arrayEx.map(async element => await getIds(element)));
return mappedResult;
}
catch (error) {
console.log(error);
return error;
}
}
The problem is that I get an array that for each existing item is wrapped inside another array that contains the actual object...
[
[
{
id: 'clcj22d650002sbdkmmobh33l',
bodyPart: 'waist',
equipment: 'body weight',
gifUrl: 'http://d205bpvrqc9yn1.cloudfront.net/0001.gif',
name: '3/4 sit-up',
target: 'abs'
}
],
[
{
id: 'clcj22d650002sbdkmmobh33l',
bodyPart: 'waist',
equipment: 'body weight',
gifUrl: 'http://d205bpvrqc9yn1.cloudfront.net/0001.gif',
name: '3/4 sit-up',
target: 'abs'
}
],
[
{
id: 'clcj22d650007sbdk9ncyidv1',
bodyPart: 'upper legs',
equipment: 'body weight',
gifUrl: 'http://d205bpvrqc9yn1.cloudfront.net/1512.gif',
name: 'all fours squad stretch',
target: 'quads'
}
]
]
This is the response of the entire function...

Javascript convert array to object to use in Find in Mongoose

I'm trying to do a dynamic filter building for a search in Mongoose.
I got an array containing various filters, and I would like to use them in this.mySchema.find ({QUERY}) as follows:
[
{ name: { '$eq': 'John' } },
{ surname: { '$regex': '.*t', '$options': 'i' } }
]
Now I would like to search by all filters as below
const query = this.customerModel.find(findFilters);
But I am getting the error below
Parameter "filter" to find() must be an object, got [object Object],[object Object]
I tried converting this to an object, but I'm getting something that I can't use either
{ ...findFilters }
Result:
{
'0': { name: { '$eq': 'John' } },
'1': { surname: { '$regex': '.*t', '$options': 'i' } }
}
I also tried this:
const result = {};
findFilters.forEach(e => result[e] = {});
But I got something that also doesn't work in Find and the filters don't work during the search
{ '[object Object]': {} }
So, how can I use my array of filters in the Find method?
You need to reduce() to a single object:
const filters = [
{ name: { '$eq': 'John' } },
{ surname: { '$regex': '.*t', '$options': 'i' } }
];
const filter = filters.reduce((a, v) => ({...a, ...v}), {});
console.log(filter);
Your result is an pending promise
you need to use an async function and use await:
const query = await this.customerModel.find(findFilters);
Or .then()
this.customerModel.find(findFilters).then(res => {
console.log(res);
})

Create new object from array

I'm trying to create new object with different properties name from Array.
Array is:
profiles: Array(1)
0:
column:
name: "profileName"
title: "Profile name"
status: "Active"
I want to create new function that return object with two properties:
id: 'profileName',
profileStatus: 'Active'
The function that I have create is returning only one property as undefined undefined=undefined.
function getProfile(profiles) {
if (!profiles.length) return undefined;
return profiles.reduce((obj, profile) => {
console.log('profiles', profile);
return ({
...obj,
id: profile.column.name,
profileStatus: profile.status,
});
}, {});
}
The function getProfile is taking as input array 'profiles' from outside,
I've just tested here and this seems to be working actually
const getProfile1 = (p) => p.reduce((obj, profile) =>({
...obj,
id: profile.column.name,
profileStatus: profile.status,
}), {});
You can use map as an alternative.
var profiles = [{"column":{"name": "profileName3","title": "3Profile name"},"status": "Active"},{"column":{"name": "profileName","title": "Profile name"},"status": "Active"}];
function getProfile(profiles) {
if (!profiles.length) return undefined;
return profiles.map(function(profile,v){
return {id:profile.column.name,profileStatus: profile.status};
});
}
console.log(getProfile(profiles));
Whenever I use reduce in this way, I usually index the final object by some sort of an id. As noted in another answer, you could use map in this situation as well. If you really want your final data structure to be an object, however, you could do something like this:
/**
* returns object indexed by profile id
*/
const formatProfiles = (profiles) => {
return profiles.reduce((obj, profile) => {
return {
...obj,
[profile.id]: {
id: profile.column.name,
profileStatus: profile.status,
}
};
}, {});
};
const profiles = [
{
id: 0,
status: 'active',
column: {
name: "profile_name_1",
title: "profile_title_1",
},
},
{
id: 1,
status: 'inactive',
column: {
name: "profile_name_2",
title: "profile_title_2",
}
}
];
const result = formatProfiles(profiles);
/**
* Result would look like this:
*/
// {
// '0': { id: 'profile_name_1', profileStatus: 'active' },
// '1': { id: 'profile_name_2', profileStatus: 'inactive' }
// }

React bad Header Request

I'm trying to build new Header Request by looping inside the API and getting specific data. What I'm trying to achieve is to get some specific data and to put in Request Payload. But the result that I'm achieving with my code seems to be wrong.
API looks like:
id: 12345
profileID: 3456
name: "Profile Name"
details: [
0: {
detailID: 4556
progressID: 5678
comment:
0: {
id: 63434
commentNumber: 34
image: 'image.jpg'
}
}
]
documents:
0: {
id: 3567
docId: 6753
docName: 'doc.pdf'
}
and what I need to achieve is:
id: 12345
details: [
0: {
detailId: {
0: 3567
}
document: {
0: 3567
}
}
]
So, tried to move inside api:
.then((response) => {
const getID: Object.values(response).map(result => result.details.map(test => test.detailID));
const getComm = Object.values(response).map(result => result.details.map(test => test.comment.map(
cId => cId.id
)));
const getDoc = Object.values(response).map(result => result.documents.map(test => test.id));
setProfile({
id: getID,
details: {
getComm, getDoc
}
})
});
and I'm achieving the result like that:
id: {
0: {
0: 12345
}
you have used Object.values, instead try with Object.keys and proceed further

normalizr v3 and JSON api

I want to normalise the responses I receive from an API. A typical response could look something like this:
// Get all projects
{data:[
{
id: 1
...
team:{
data: {
id:15
...
}
}
},
{
id:2,
....
},
{
id:3,
...
}
]}
How do I write my schemas so that it removes the 'data' container?
Currently, my schema looks like:
export const project = new schema.Entity('projects', {
team: team, // team omitted
},
{
processStrategy: (value, parent, key) => parent.data
}
)
export const arrayOfProjects = new schema.Array(project)
And I am using it like:
const normalizedProjects = normalize(jsonResponse, arrayOfProjects)
normalizedProjects then looks like this:
{
entities:{
projects:{
undefined:{
0:{
team:{
data:{
id:15,
...
}
}
},
1:{...},
2:{...}.
...
50:{...},
}
}
},
result:[] // length is 0
}
I'm not sure why the list of projects is contained in 'undefined', either?
I also use json_api schema.
How about like this?
const projectsSchema = new schema.Entity('projects', {}, {
processStrategy: processStrategy
});
export const processStrategy = (value, parent, key) => {
const attr = value.attributes;
delete value.attributes;
return { ...value, ...attr };
};
export const fetchProjectsSchema = {
data: [projectsSchema]
}
Each of your entity schema that you want to have the data omitted (or anything else fundamentalyl changed) needs to include a processStrategy that you write to remove or change any data. (see more examples in the tests)

Categories

Resources