Search code examples
javascriptnode.jsecmascript-6lodash

Object Destructuring


How can I write this code in more elegant way. I have looked on lodash etc. but couldn't actually find the best way to destructure object for my needs. Because I will write those properties on mongo I also tried to verify if they are exist or not.

 const { _id, name, bio, birth_date, photos, instagram, gender, jobs, schools } = element
    let myPhotos = photos.map((photo) => photo.id)
    let insta = {}
    if (instagram) {
        insta.mediaCount = instagram.media_count
        insta.profilePicture = instagram.profile_picture
        insta.username = instagram.username
        insta.photos = instagram.photos.map((photo) => photo.image)
    }

    const doc = {}

    doc._id = ObjectId(_id)
    doc.name = name
    doc.birthDate = new Date(birth_date)

    if (bio.length) {
        doc.bio = bio
    }
    if (myPhotos.length) {
        doc.photos = myPhotos
    }
    if (Object.keys(insta).length) {
        doc.instagram = insta
    }
    doc.gender = gender

    if (jobs.length) {
        doc.jobs = jobs
    }

    if (schools.length) {
        doc.schools = schools
    }

    try {
        await collection.insertOne(doc)
    } catch (error) {
        console.log("err", error)
    }

Solution

  • You could define the doc all at once using the ternary operator to test conditions. If the undefined properties need to be removed, then you can remove them via reduce afterward.

    const { _id, name, bio, birth_date, photos, instagram, gender, jobs, schools } = element
    const myPhotos = photos.map(({ id }) => id)
    const insta = !instagram ? undefined : (() => {
      const { media_count, profile_picture, username, photos } = instagram;
      return {
        mediaCount: media_count,
        profilePicture: profile_picture,
        username,
        photos: photos.map(({ image }) => image)
      }
    })();
    const docWithUndef = {
      _id: ObjectId(_id),
      name,
      gender,
      birthDate: new Date(birth_date),
      bio: bio.length ? bio : undefined,
      photos: myPhotos.length ? myPhotos : undefined,
      instagram: insta,
      jobs: jobs.length ? jobs : undefined,
      schools: schools.length ? schools : undefined,
    }
    const doc = Object.entries(docWithUndef)
    .reduce((accum, [key, val]) => {
      if (val !== undefined) accum[key] = val;
      return accum;
    });
    try {
      await collection.insertOne(doc)
    } catch (error) {
      console.log("err", error)
    }
    

    Note the destructuring of the arguments to reduce the syntax noise, and the use of const rather than let (improves code readability).