Reputation: 7601
I have an array context.buildingFields.finished
that looks like this:
[{ name: 'a' type: 'text', value: '1' }, { name: 'b' type: 'file', value: '2' }]
And I have a function that loops through that array to create a new one context.createPanoramasPayload
with only the fields of type file
:
function handleCreatePanoramas (uploadedPhoto, context, callback) {
const panoramasFields = context.buildingFields.finished
context.createPanoramasPayload = panoramasFields.map(field => {
if (field.type !== 'file') return
return {
name: 'index',
value: uploadedPhoto
}
})
callback(context.createPanoramasPayload)
}
}
I thought I would produce something like this (say with only one field of type file
):
[{ name: 'b' type: 'file', value: '2' }]
However, what I'm getting is something like this:
[undefined, { name: 'b' type: 'file', value: '2' }]
Why is this? And how to modify the code to achieve what I want?
Upvotes: 0
Views: 50
Reputation: 24915
This answer is an extension to @trincot's answer.
Using .filter
+ .map
is not wrong, but it adds to extra iterations. Both these functions have their own specific use-case but when you need to do both, .reduce
is more suited as you can manually parse object and return custom array/object.
Sample
context.createPanoramasPayload = panoramasFields.reduce(function(p, c) {
if (c.type === 'file')
p.push({
name: 'index',
value: uploadedPhoto
});
return p;
}, [])
Also note the use of anonymous function instead of arrow function(=>
).
What arrow function does is it binds current context to the passed callback function, so that we can use this
inside the callback. If you are using arrow function but not using this
inside callback, you are wasting the efforts engine puts in binding context to the callback. For this reason, if you do not use this
, in my understanding, its better to use anonymous function instead of arrow function.
Though its not wrong, but in my POV, it is a bad practice.
Upvotes: 0
Reputation: 350127
map
returns an array that has the same length as the given array. It does not help to return
just like that, as that will generate an undefined
value in your mapped array. Instead you need to apply filter
first:
context.createPanoramasPayload = panoramasFields.filter(field => {
return field.type === 'file';
}).map(field => {
return {
name: 'index',
value: uploadedPhoto
}
})
This keeps with a functional way of programming.
As a side note, since the callback functions now don't do anything else than return something, you can use the expression syntax for the arrow functions:
context.createPanoramasPayload = panoramasFields
.filter(field => field.type === 'file')
.map(field => ({
name: 'index',
value: uploadedPhoto
}));
Upvotes: 3
Reputation: 2038
You are using map function here, that means it will not reduce the length of the array. It return same length array. So use filter to get result.
Upvotes: 0