1

I am trying to create an object to use in various places of HTML. It goes a little something like this:

MovieInfo = {
            title: Movie.value[0].title,
            meta: [
              {
                name: "description",
                content: Movie.value[0].description,
              },
              {
                name: "date",
                content: Movie.value[0].releasedate
              },
              // Try to add objects from another array
             Movie.value[1].forEach(function (Cast, index) {
             return {
                key: Cast.actorname, property: "article:tag", content: Cast.actorname
              }
          })
            ]
}

The above does not work. However if I push to the meta array after creating the MovieInfo object then it does work, like so:

MovieInfo = {
                title: Movie.value[0].title,
                meta: [
                  {
                    name: "description",
                    content: Movie.value[0].description,
                  },
                  {
                    name: "date",
                    content: Movie.value[0].releasedate
                  },
                 
                ]
    }

              // Try to add objects from another array
                 Movie.value[1].forEach(function (Cast, index) {
                 MovieInfo.meta.push({
                    key: Cast.actorname, property: "article:tag", content: Cast.actorname
                  })
              })

I have to do quite a few of these loops in different areas so I would prefer them to be done while creating MovieInfo than outside of it. Is that possible? That is, is it possible to make my first attempt work by having a loop inside the object creation itself?

volume one
  • 6,800
  • 13
  • 67
  • 146
  • "*Is that possible?*" No. And I'm not sure why you think having the same code but in a different place is more convenient. Presumably you just create this once and then consume it later. Why does it really matter how it is created and populated with data? – VLAZ Jun 09 '21 at 16:49
  • @VLAZ Readability and knowing everything to do with the object creation is in the object creation itself. Can you explain *why* it is not possible? – volume one Jun 09 '21 at 16:51
  • Because you cannot use loops in object initialiser syntax. – VLAZ Jun 09 '21 at 16:52
  • It's really unclear what you're trying to achieve. You already have an array of movie objects. Why are you trying to assign that to a new object? – Andy Jun 09 '21 at 16:57
  • 1
    @Andy remapping it to a new shape, it seems. I swear, some days that's most of what I do at work - just transform objects into other objects. Surely it's not abnormal. – VLAZ Jun 09 '21 at 16:58
  • No, it's not. It just seems unnecessary in this case. But, yes. Totally abnormal. – Andy Jun 09 '21 at 17:09
  • @Andy Do you mean why am I creating the `MovieInfo` object from a bunch of arrays? I have to create it in a specific way to be consumed by a specific external library function that requires it in that format – volume one Jun 09 '21 at 18:40

1 Answers1

2

You can use an IIFE to do arbitrary things in an object literal (or really, any expression):

const MovieInfo = {
  title: Movie.value[0].title,
  meta: (() => {
    const meta = [
      {
        name: "description",
        content: Movie.value[0].description,
      },
      {
        name: "date",
        content: Movie.value[0].releasedate
      },
    ];
    for (const cast of Movie.value[1]) {
      meta.push({
        key: cast.actorname,
        property: "article:tag",
        content: cast.actorname
      });
    }
    return meta;
  })(),
};

In this case, I would however recommend to simply build the array using concat and map:

const MovieInfo = {
  title: Movie.value[0].title,
  meta: [
    {
      name: "description",
      content: Movie.value[0].description,
    },
    {
      name: "date",
      content: Movie.value[0].releasedate
    },
  ].concat(Movie.value[1].map(cast => ({
    key: cast.actorname,
    property: "article:tag",
    content: cast.actorname
  }))),
};
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • This is great. Being new to JS, I have not come across this syntax for arrow function before `cast => ({ key: cast.actorname, property: "article:tag", content: cast.actorname})`. I thought arrow functions were just `cast => { //do stuff here }`. How come yours has parenthesis and is this documented anywhere so I can learn it? – volume one Jun 09 '21 at 19:51
  • 1
    @volumeone See [ECMAScript 6 arrow function that returns an object](https://stackoverflow.com/q/28770415/1048572). Alternatively you could write `cast => { return {…}; }` – Bergi Jun 09 '21 at 19:56