0

I'm using Express and have an array of objects. I would like to modify the created property (I am using dateFormat package) for presentation.

The array is the result of a mongo query and is assigned to a variable stories and looks like:

[
    { public: false,
      keyStageLevel: [ 'ks1' ],
      created: 2018-03-25T13:01:30.809Z,
      _id: 5ab79daafa832035b416536f,
      slug: 'goldilocks',
      name: 'Goldilocks',
      comments: null,
      id: '5ab79daafa832035b416536f' },
    { public: false,
      keyStageLevel: [ 'ks1' ],
     created: 2018-03-25T13:07:22.421Z,
     _id: 5ab79f0afa832035b4165370,
     slug: 'cinderella',
     name: 'Cinderella',    
     comments: null,
     id: '5ab79f0afa832035b4165370' },
   ..
]

If I execute

stories.map(function(story){
    story.created = dateFormat(story.created, "dddd, mmmm dS, yyyy, h:MM:ss TT")
    console.log('AFTER TRANSFORM '+story.created);
});

The console.log shows the date format I want but the story.created values in the stories array is unmodified. What is the correct way (ES5 if possible, I'm learning and I find it easier to understand what is going on) to reformat the created property in the stories array?

Edit - showing the query and use of .map and .foreach both of which leave `stories' unmodified

let stories = await Story.find({$or:[{'group': {$in:group}}, 
  {'public':true} ]})
    .populate('group')
    .populate('createdBy');
console.log('BEFORE TRANSFORM '+stories);
// console.log(stories);
// stories.map(function(story){
//     story.created = dateFormat(story.created, "dddd, mmmm dS, yyyy, h:MM:ss TT")
//     console.log('AFTER TRANSFORM '+story.created);
// });
stories.forEach(story => {
    story.created = dateFormat(story.created, "dddd, mmmm dS, yyyy, h:MM:ss TT")
});
console.log('AFTER TRANSFORM '+stories);
4
  • .map expects a return value - do a forEach - stories.forEach(function(story){ Commented Apr 20, 2018 at 19:23
  • Assuming you do not assigne the result of stories.map to a variable, where and how do you check the values in the stories? Create a minimal and reproducable example. Commented Apr 20, 2018 at 19:26
  • @tymeJV I agree that .forEach shoudl be use here. But it would not explain the problem the OP has. Because if the OP would do stories = stories.map then stories would be an array containing only undefined, but the OP says that the values are unchanged. And if the OP really wrote stories.map without asigning the new array to a variable, then result of stories.map and stories.forEach, would be the same. Commented Apr 20, 2018 at 19:31
  • I agree @t.niese - I'm guessing OP has some more code that may be affecting this that we're not seeing. Commented Apr 20, 2018 at 19:36

2 Answers 2

2

As others note, you're misusing map. My choice, though, would be to use map properly, and create a new array from your old one. I think it's much easier to reason about data that is not mutated. Here's one way to do that:

const stories = [{"_id": "5ab79daafa832035b416536f", "comments": null, "created": "2018-03-25T13:01:30.809Z", "id": "5ab79daafa832035b416536f", "keyStageLevel": ["ks1"], "name": "Goldilocks", "public": false, "slug": "goldilocks"}, {"_id": "5ab79f0afa832035b4165370", "comments": null, "created": "2018-03-25T13:07:22.421Z", "id": "5ab79f0afa832035b4165370", "keyStageLevel": ["ks1"], "name": "Cinderella", "public": false, "slug": "cinderella"}]

const dateFormat = (d) => d.slice(0, 10) // dummy

const updatedStories = 
    stories.map(story => ({...story, created: dateFormat(story.created)}))

console.log(updatedStories)

If that ES6 bothers you, then you could replace it with

stories.map(story => Object.assign({}, story, {created: dateFormat(story.created)}))
Sign up to request clarification or add additional context in comments.

1 Comment

Many thanks to everyone for their answers and discussion. I'm marking this one as the answer because it works for me
-1

You may wanna consider forEach():

stories.forEach(story => {
    story.created = dateFormat(story.created, "dddd, mmmm dS, yyyy, h:MM:ss TT")
});

Docs: Array.prototype.forEach() - JavaScript | MDN

5 Comments

This would not explain but the story.created values in the stories array is unmodified. If the return story; would be the problem then the OP would have a list of undefined and not of unchanged story objects.
This is really missleading. stories.map does not change the original array, that's true, but story.created = ... will still have an effect on the element that is stored in stories. So stories.map(story => { story.created = ... ; return story; }); and stories.forEach(story => { story.created = ...; }` has the same effect on the story.created of the elements in stories. Check this jsfiddle
.map returns a new array with changes and the original array remains unchanged your approach is mutating the original array's objects.
@t.niese I see what you mean, thanks for your input. I have updated my answer.
@Ele Thanks for your input, I have updated my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.