0

I have a situation where I have an array of objects like this:

[
    {
        "name": "Phone call",
        "value": "Phone call"
    },
    {
        "name": "SMS",
        "value": "SMS"
    },
    {
        "name": "Email",
        "value": "Email"
    }
]

I have to remap the above OBJ to a new one containing its translation which is similar to this from React-intl: formatMessage(formatMessage(messages.emailOptionPlaceholder)

And the idea is as follow:

if (obj.name === 'Email') formatMessage(formatMessage(messages.emailOptionPlaceholder) else obj.name

so the new array should contain the right translation which will populate a dropdown menu.

I tried so far like this but without success:

field.options.map(o => {
        return [
          o.name === 'Email'
            ? formatMessage(messages.emailOptionPlaceholder)
            : o.name,
          o.name === 'Phone call'
            ? formatMessage(messages.phoneOptionPlaceholder)
            : o.name,
          o.name === 'SMS'
            ? formatMessage(messages.smsOptionPlaceholder)
            : o.name,
        ];
      });

This gives back 3 arrays instead of one with the values I need.

My goal is to have an array containing the formatMessage(...) output for the 3 elemnts inside the object as example of the output:

[{
  name: Phone call
  value: <-- Phone call translation from formatMessage --> 
 }
{
  name: Email
  value: <-- Email translation from formatMessage --> 
 }
{
  name: SMS
  value: <-- SMS call translation from formatMessage --> 
 }
]

I'm getting that OBJ from back-end and need to put the translation of corresponding name inside a drop down menu and was wondering what solution can be better.

2
  • 1
    Could you provide a minimal working example? With all the code involved. The return values form the function etc. are currently unclear. Commented Nov 23, 2021 at 15:00
  • 1
    That is because you are wrapping your return in an array return [ ... ] Commented Nov 23, 2021 at 15:04

2 Answers 2

1

I would do it something like this. (not tested)

const mappings = {
    'Email': messages.emailOptionPlaceholder,
    'Phone call': messages.phoneOptionPlaceholder,
    'SMS': messages.smsOptionPlaceholder
};

const mapped = field.options.map((obj) => {
    const key = mappings[obj.name]
    if (key) {
        return {
            ...obj,
            value: formatMessages(key)
        }
    } else {
        // no mapping for object name.
        // do something to handle it or just return obj
        return obj
    }
}

If you are only interested in the values you can do this.

const mappings = {
    'Email': messages.emailOptionPlaceholder,
    'Phone call': messages.phoneOptionPlaceholder,
    'SMS': messages.smsOptionPlaceholder
};

const mapped = field.options.map((obj) => {
    const key = mappings[obj.name]
    return formatMessages(key) || key //
}
Sign up to request clarification or add additional context in comments.

2 Comments

I tried this but how can I return only the value and use that to populate a drop down menu? asking becasue I see the translation but the drop-down is populated still with the English name and not arabic
How to populate depends on the nature of your dropdown and if you are using a frontend library. In vanilla HTML / js you will probably need to add the options with javascript. But to only get the values in the array is straightforward. I'll edit my answer
1

Using .map is a possible solution, however you are not using it correctly. From mdn:

The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

To fix your solution, you can use the following code:

field.options.map((o) => {
  if (o.name === "Email") {
    return { ...o, value: formatMessage(messages.emailOptionPlaceholder) };
  } else if (o.name === "Phone call") {
    return { ...o, value: formatMessage(messages.phoneOptionPlaceholder) };
  } else if (o.name === "SMS") {
    return { ...o, value: formatMessage(messages.smsOptionPlaceholder) };
  } else {
    return o;
  }
});

Note that .map returns a new array, so you need to save the result. If you want to mutate the objects directly, then use a simple forEach , like so:

field.options.forEach(o => {
      if (o.name === "Email") {
        o.value = formatMessage(messages.emailOptionPlaceholder);
      } else if (o.name === "Phone call") {
        o.value = formatMessage(messages.phoneOptionPlaceholder);
      } else if (o.name === "SMS") {
        o.value = formatMessage(messages.smsOptionPlaceholder);
      }
    })

1 Comment

Yes I need to add options to dropdown menu so I need the results to go there. Maybe the foreach is not ok and better a map in my situation?

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.