Using `map` to Create New Array of Objects with Fewer Properties - javascript

I am wanting to use map to create a new array of of objects that have two properties from the original objects in the originating array, so I am trying this:
const filteredConfigurableModules = configurableModules.map(module =>
module.name, module.configurables
);
But this isn't working, as only the "name" is saved to the new array. What am I missing here?
I also tried this:
const filteredConfigurableModules = configurableModules.map(module => {
name: module.name,
configurables: module.configurables
});
... but end up with a syntax error:
SyntaxError: Unexpected token ':'

As I see you want to map from one array to another. You can do it in 2 ways:
Inline
const filteredConfigurableModules = configurableModules.map(module => ({name: module.name, configurables: module.configurables}));
When you do inline and return an object you have to wrap it in parenthesis so that it gets evaluated properly.
Use Return Statement
const filteredConfigurableModules = configurableModules.map(module => {
return {
name: module.name,
configurables: module.configurables
};
});

You should wrap it with parentheses as follow:
const filteredConfigurableModules = configurableModules.map(({name, configurables})=> ({
name,
configurables
}));

You can create a new object on the arrow function from the map:
const filteredConfigurableModules = configurableModules.map(module =>
({ name: module.name, configurables: module.configurables })
);
this return an array of objects with name and module fields.
If you return an object, you need to use parenthesis because otherwise it will be treated as a code body with no return.

Can you try this if i understand your question correctly
const filteredConfigurableModules = configurableModules.map(module => ({
name : module.name,
configurables : module.configurables,
}));

Related

How to define a function in javascript reduce function?

I have an object student, it has property id, name, groupName.
allStudents is the array of student objects, I want to turn it to an id to student map, but for each student, I want to generate a new property "label", if the student has groupName, label value is "name + groupName", otherwise it is name. So I write below code, it works:
const idsToStudents = allStudents.reduce((tempMap, student) => {
const getStudentLabel = (student) => {
if (student.groupName) {
return [student.name, `(${student.groupName})`].join(' ');
}
return student.name;
};
const studentLabel = getStudentLabel(student);
return {
...tempMap,
[student.id]: { ...student, label: studentLabel}
};
}, {});
I define getStudentLabel function inside reducer function, is there a better way to do this instead of declare getStudentLabel function again and again in the reducer function? You can ignore what exactly getStudentLabel does, just think it takes each person as parameter and return something based on person, is there a way to define the function only once, but still I can call it for each person in the reducer?
Thank you!
You are passing student as a parameter to the function, so you don't need to declare it inside the reduce. This would work as well:
const getStudentLabel = (student) => {
if (student.groupName) {
return [student.name, `(${student.groupName})`].join(' ');
}
return student.name;
};
const idsToStudents = allStudents.reduce((tempMap, student) => {
const studentLabel = getStudentLabel(student);
return {
...tempMap,
[student.id]: { ...student, label: studentLabel}
};
}, {});
And you can also shorten the code a bit:
const getStudentLabel = ({ name, groupName }) => groupName
? `${name} (${groupName})`
: name;
const idsToStudents = allStudents.reduce((tempMap, student) => ({
...tempMap,
[student.id]: { ...student, label: getStudentLabel(student) }
}), {});
I wouldn't worry about redefining functions inside closures. Any reasonable javascript implementation will optimize that so that minimal extra memory is being used. I wouldn't say its accurate to say that you're "defining" the function more than once - you are only defining it once in your code. The function is being instantiated each time, but this instantiation will take advantage of caches of the static parts of the the function. So your way of doing it is perfectly fine. As Ori Drori mentioned, you don't have to have the student variable in the inner function, but it might be a good idea to anyway, so that you're very explicit about the function's dependencies.
Object.fromEntries can work instead of reduce.
const getStudentLabel = ({name, groupName}) => groupName
? name + ` (${groupName})`
: name;
const idsToStudents = Object.fromEntries(
allStudents.map(student => [student.id, { ...student, label: getStudentLabel(student) }])
);

How to destructure and reassign in one line using JavaScript [duplicate]

This question already has answers here:
One-liner to take some properties from object in ES 6
(12 answers)
Closed 1 year ago.
I have an object adData and I need to extract some of it's properties, add some more properties to the extracted object and pass the object as parameter. I can do this using:
const params = {};
params.id = adData.id;
params.status = adData.status;
params.frequency = adData.frequency;
params.user = getLoggedInUser();
callAnotherFunction(params)
Can I do the destructing and reassigning to new object in one line ? Something like:
const params = {id, status, frequency} = adData;
params.user = getLoggedInUser();
Or
const params = {id, status, frequency, getLoggedInUser(): user} = adData;
Now these both above syntaxes are wrong but is there any other way to do it using destructuring and without extracting the properties one by one
If you know what properties the object does have, and there aren't that many, you can list them and use rest syntax to gather the others into an object:
const { unwantedProp, ...params) = adData;
// use params
Otherwise, there isn't any incredibly simple syntax for what you want, though you could
const params = Object.fromEntries(
Object.entries(adData).filter(([key]) =>
['id', 'status', 'frequency'].includes(key)
)
);
We can do in one line with destructuring and arrow function.
const getLoggedInUser = () => "foo";
const adData = {
id: 123,
status: "active",
frequency: "less",
bar: 4,
};
const params = (({ id, status, frequency }, user = getLoggedInUser()) => ({
id,
status,
frequency,
user,
}))(adData);
console.log({ params });

How to transform queried data to an array FaunaDB typescript?

I could display the result of my pagination query (FaunaDB,FQL) in the console and it appears as a javascript object. Yet, I cannot access the properties of said object and even less can I convert it to an array using the spread operator. How could I do that?
I am aware there exists a pagination helper but could not make it work, as explained above. Here is the latest code I am trying:
var array=[]
qu(q.Map(
q.Paginate(q.Match(q.Index('FeesByIndex'))),
q.Lambda(x => q.Get(x))
)).then(res => { console.log(res); array=[...res] })//the log really looks like a js object and res is said to be one
It says type object is not an array type. Also, property data is said not to exist on res, although it clearly does in the console
You missed to specify the index term and the Lambda has syntax errors.
The response object has a data property, which is a list.
In my repositories I use this snippet if the query returns multiple object:
const result: Fee[] = [];
await CLIENT.query(
q.Map(
q.Paginate(
q.Match(
q.Index('FeesByIndex'),
'index term',
),
),
q.Lambda('fees', q.Get(q.Var('fees'))),
)
)
.then(faunaResponse => {
const dataArray = faunaResponse.data;
dataArray.forEach(s => {
const data = s.data;
result.push({
id: data.id,
yourProp1: data.yourProp1,
yourProp2: data.yourProp2,
});
});
})
.catch(e => logger.error(e));
would you try this way?
var array=[]
qu(q.Select(['data'],
q.Map(
q.Paginate(q.Match(q.Index('FeesByIndex'))),
q.Lambda(x => q.Get(x))
)
)
).then(res => { console.log(res); array=[...res] })

React typescript Property 'map' does not exist on type 'User'

I am trying to use react with typescript. I have initialized useState with an object but can't use map function with that object.
Here is the error I am getting
Property 'map' does not exist on type 'User'
Here is the code.
Thank you in advance
interface User {
name : string,
email : string,
stream_key : string,
}
const App = () => {
const [liveStreams, setLiveStreams] = useState<User>({
name : '',
email : '',
stream_key : ''
})
// setting livestreams
const getStreamsInfo = (live_streams) => {
axios.get('http://192.168.43.147:4000/streams/info', {
}).then(res => {
console.log(res.data)
setLiveStreams({
name: res.data.name,
email: res.data.email,
stream_key: res.data.stream_key
})
});
}
return (
{liveStreams.map(data => <Text>{data.email}</Text>)}
)
You only have a single User object, not an array of them. Either:
Just use the object (and ideally use the singular rather than the plural for the name of the state variable), or
Use an array of objects instead.
With #1, for instance, if you used the name liveStream, it would look like this:
return <Text>{liveStream.email}</Text>;
Given that you've said
Actually res.data contains data of multiple users. How to use array of objects using typescript? Sorry for newbie questio
in a comment, it looks like you want #2, which means:
Make your initial data an empty array.
const [liveStreams, setLiveStreams] = useState<User[]>([]);
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^−−^^
When you receive the list, use the whole list:
const getStreamsInfo = (live_streams) => {
axios.get('http://192.168.43.147:4000/streams/info', {
}).then(res => {
// To *replace* state with the list in `res.data`:
setLiveStreams(res.data);
// >>OR<< to **add to** the current state, appending the list from `res.data`:
setLiveStreams(streams => [...streams, ...res.data]);
});
}
Add key attributes to your Text elements, since they're entries in an array.
In your case, the actual solution will be to use a type guard to check that you have an array before attempting to use the map method.
if (liveStreams instanceof Array) {
liveStreams.map(data => <Text>{data.email}</Text>);
}
interface User {
name : string,
email : string,
stream_key : string,
}
const App = () => {
const [liveStreams, setLiveStreams] = useState<User[]>([{
name : '',
email : '',
stream_key : ''
}])
// setting livestreams
const getStreamsInfo = (live_streams) => {
axios.get('http://192.168.43.147:4000/streams/info', {
}).then(res => {
console.log(res.data)
// is the `res.data` an Array Object?
// or u may just do like that
/*
* const { data } = res
* // if `data` type is user[]
* setLiveStreams(data)
*/
setLiveStreams([{
name: res.data.name,
email: res.data.email,
stream_key: res.data.stream_key
}])
});
}
return (
{liveStreams.map(data => <Text>{data.email}</Text>)}
)

React add label to nested array object in Object.keys map

I have a React component which is pulling JSON data via an axios.get call and then I am mapping an embedded object using the following function:
axios.get('MasterData.json').then(response => {
const fullTree = response.data.graph.tree;
const resultTree = Object.keys(fullTree).map(key => ({
...fullTree[key],
id: key
}));
This produces the following:
{5bd356cc-5ee6-49a0-ab68-65cbf0209105: Array(6), id: "5bd356cc-5ee6-49a0- ab68-65cbf0209105"}
which is great, but I need to add a label of "ports: to the entire nested array (Array(6)) that is being output above so that I can map it. Any help is appreciated.
axios.get('MasterData.json').then(response => {
const fullTree = response.data.graph.tree;
console.log(fullTree) // you must check this fist
const resultTree = Object.keys(fullTree).map(key =>
new Port({ // create some function to generate get port as you want
port : fullTree[key],
id: key
)
});
for create function maybe on bellow me can explain more :)

Categories