0

I need to map over array of objects and change "photo property" in every object into it's base64 representation from the url im storing in databse. For this purpose I'm using imageToBase64 library for node.js. But the problem is I cannot generate the same array with just changed properties. Tried lot of times with destructuring, returning in different ways and I still got either undefined or unchanged array. What is more when I console log as shown in code block, it logs correctly changed objects but in different order (second user go first in console and first user go second). Where's the problem and how to just get the same array but with converted "photo property in every object" to be able to send it over http? Here's my code:

const getUsers = asyncHandler(async (req, res) => {
  const userRecords = await userRecord.find({ appUser: req.appUser.id });
  const convertedRecords = userRecords.map((record) => {
    imageToBase64(record.photo)
      .then((response) => {
        record.photo = response
        console.log(record)
      })
      .catch((error) => {
        console.log(error);
      });
      //SHOULD RETURN SOMETHING
      
  });
  
  res.status(200).json(userRecords);
});

And this is how my schema looks like:

const userRecordSchema = mongoose.Schema(
  {
    appUser: {
      type: mongoose.Schema.Types.ObjectId,
      required: true,
      ref: "appUser",
    },
    firstName: {
      type: String,
    },
    lastName: {
      type: String,
    },
    email: {
      type: String,
    },
    age: {
      type: Number,
    },
    photo: {
      type: String,
    }
  },
  {
    timestamps: true,
  }
);

module.exports = mongoose.model("UserRecord", userRecordSchema);
Morghot2
  • 5
  • 2

1 Answers1

0

If think you need to add some return :

const getUsers = asyncHandler(async (req, res) => {
    const userRecords = await userRecord.find({ appUser: req.appUser.id });
    const convertedRecords = await Promise.all(userRecords.map((record) => {
      return imageToBase64(record.photo) // return the result of convertion
        .then((response) => {
            return {...record, _doc: {...record._doc, photo: response} }; // return the re structured object instead of modify
        })
        .catch((error) => {
          console.log(error);
        });
        //SHOULD RETURN SOMETHING
        
    }));

    console.log(convertedRecords); // should print the expected result
    
    res.status(200).json(userRecords);
  });

You need to add a return statement inside a .map callback.
Also, when you need to return the edited record, just edit the record will not change the result of imageToBase64.

I'm not 100% sure as I can't test your code, but I think this can helps you

nem0z
  • 1,060
  • 1
  • 4
  • 17
  • Unfortunately doesn't work - when I do this and try to console log my convertedRecords just before my http response it logs `[undefined, undefined]` ; / But thanks! – Morghot2 Aug 10 '22 at 13:23
  • It's on me, I will fix it [Done]. I added an `await` + `Promise.all()` to resolve the array of `promises` and allow you print the result – nem0z Aug 10 '22 at 13:28
  • Thanks, It worked but not 100% as expected : ) now instead of changing the photo url into base 64 the original url remains the same and what is happening it is adding some internalcache object and the converted base64 string is added after the record object so the output looks like this: – Morghot2 Aug 10 '22 at 13:54
  • `{ '$__': InternalCache { activePaths: [StateMachine], skipId: true, strictMode: true, selected: {}, fields: {}, exclude: null }, '$isNew': false, _doc: { _id: new ObjectId("62f0fd518b8a4bef6a3f3c32"), appUser: new ObjectId("62cc8e32f8b14860999b77d9"), firstName: 'User', lastName: 'First', email: 'first@gmail.com', age: 12, photo: "ORIGINAL URL", createdAt: 2022-08-08T12:10:57.380Z, updatedAt: 2022-08-08T12:10:57.380Z, __v: 0 }, photo: "BASE64 " }` – Morghot2 Aug 10 '22 at 13:55
  • Does "BASE64" has the expected value ? – nem0z Aug 10 '22 at 14:23
  • Yes - it does (I just cut it because comment would be too long). The code just adds the BASE64 after my object not changing the inside value – Morghot2 Aug 10 '22 at 14:30
  • I edited, it should works now – nem0z Aug 10 '22 at 14:41
  • Ahah, thx. Don't forget to click "accept the answer" if it fully satisfied your initial question. Have a nice day ;) – nem0z Aug 10 '22 at 15:20