Reputation: 699
I have a Map
object:
let dateJobMap = new Map();
for (let jobInArray of this.state.jobs) {
let deliveryDate: Date = new Date(jobInArray.DeliveryDate);
let deliveryDateString: string = deliveryDate.toLocaleDateString("en-US");
if (dateJobMap.has(deliveryDateString)) {
let jobsForDate: IDeliveryJob[] = dateJobMap.get(deliveryDateString);
jobsForDate.push(jobInArray);
}
else {
let jobsForDate: IDeliveryJob[] = [jobInArray];
dateJobMap.set(deliveryDateString, jobsForDate);
}
}
In my render
method, I want to call a TruckJobComp object for each delivery job in the value's array to display it:
<div className={ styles.column }>
<p className={ styles.description }>{escape(this.props.description)}</p>
{
dateJobMap.forEach(function(jobsForDate, dateString) {
jobsForDate.map(job => (
<TruckJobComp job = { job } />
))
})
}
</div>
This seems like it should work but doesn't. It never creates a TruckJobComp. I do a .forEach
iteration on my Map
, and for each value
's array
, I use .map
to get the individual job object to send to TruckJobComp object.
When I create a temp array
to grab the jobs from the last loop:
let tempJobs: IDeliveryJob[];
and in the loop add in:
if (dateJobMap.has(deliveryDateString)) {
let jobsForDate: IDeliveryJob[] = dateJobMap.get(deliveryDateString);
jobsForDate.push(jobInArray);
tempJobs = jobsForDate;
}
and then use that array
in the render:
<div className={ styles.column }>
<p className={ styles.description }>{escape(this.props.description)}</p>
{
tempJobs.map(job => (
<TruckJobComp job = { job }/>
))
}
</div>
It displays as expected.
I do have a warnings in Visual Studio Code:
Warning - tslint - ...\TruckDeliverySchedule.tsx(104,38): error no-function-expression: Use arrow function instead of function expression
I don't know enough to understand. Line 104 corresponds with:
dateJobMap.forEach(function(jobsForDate, dateString) {
I am very new to this so I'm not 100% sure how most of this works. Just trying to put pieces I've learned together to get things to work.
Second Edit:
{escape(this.props.description)}
{
[...dateJobMap.keys()].map(jobsForDate => // line 154
jobsForDate.map(job => (
<TruckJobComp job = { job } />
))
)
}
Produces error:
[09:06:56] Error - typescript - src\...\TruckDeliverySchedule.tsx(154,27): error TS2461: Type 'IterableIterator<any>' is not an array type.
Upvotes: 25
Views: 64430
Reputation: 880
If you want to iterate the value set using Typescript, rather than iterating the key set use this method. But don't forget to update the target es version in the tsconfig.json file under compilerOptions
[...p.delData_c.entries()].map(([key, value]) =>
<PickedIItemPack group={value} />
)
in tsconfig.json add this line
"target": "es2015"
under compilerOptions scope
Upvotes: 0
Reputation: 1262
To iterate over a Map, we can use for..of and forEach() loop constructs. Map provides three methods that return iterable: map.keys(), map.values() and map.entries().
Iteration over Maps is always in insertion order.
let map = new Map()
map.set("one", "first element");
map.set("two", "second element");
map.set(3, "third element");
for (let [key, value] of map) {
console.log(key+" : "+value);
}
map.keys() - Returns an iterable for keys
map.values() - Returns an iterable for values
map.entries() - Returns an iterable of key,value
Example
for (let key of map.keys()) {
console.log(key);
}
// output
// one
// two
// 3
for (let value of map.values()){
console.log(value);
}
// output
// first element
// second element
// third element
for (let [key, value] of map.entries()) {
console.log(key + " = " + value)
}
//output
// one = first element
// two = second element
// 3 = third element
map.forEach(function(value, key) {
console.log(key + " = " + value);
})
//output
// one = first element
// two = second element
// 3 = third element
Upvotes: 0
Reputation: 222369
dateJobMap.forEach(...)
returns undefined
, so it cannot be mapped to a collection of elements.
ES6 maps have forEach
method for compatibility purposes (generally for..of
is preferred to iterate over iterables) and don't have map
method. A map should be converted to array first, then it could be mapped to an element. Since values aren't used, only keys need to be retrieved:
{
[...dateJobMap.keys()].map(jobsForDate =>
jobsForDate.map(job => (
<TruckJobComp job = { job } />
))
)
}
Upvotes: 36
Reputation: 1380
All this warning is saying is that instead of using the syntax function(jobsForDate, dateString) {}
you should use the syntax (jobsForDate, dateString) => {}
.
The reason could be the way this
is scoped in arrow functions versus function expressions. See this post.
My guess as to the reason your first approach didn't work but your second one did is that forEach
doesn't actually return an array, and if it did, calling map
within forEach
would return an array of arrays (but, again, it doesn't). Not sure how React would handle that, but React does know how to handle a single array, which is what your last approach returns.
Upvotes: 2