0

I have this data:

const fetchedServices = [
  {
    _id: "5ee71bbfa7e903bfe2b324b2",
    en: {
      title: 'Leasing Equipment EN',
      description: 'We offer short and long term leases of both new and existing containers. New container equipment ex. works or positioned to your place of demand and existing containers from our depots.'
    },
    nl: {
      title: 'Leasing Equipment NL',
      description: 'We offer short and long term leases of both new and existing containers. New container equipment ex. works or positioned to your place of demand and existing containers from our depots.'
    },
  },
  {
    _id: "5ee73429a7e903bfe2b324b3",
    en: {
      title: 'Lease Purchase EN',
      description: 'The Lease Purchase Option we offer usually fulfills the requirements of the shipping lines, forwarders, terminals and other companies in the Transport industry, for their long term investment in containers and related equipment.'
    },
    nl: {
      title: 'Lease Purchase NL',
      description: 'The Lease Purchase Option we offer usually fulfills the requirements of the shipping lines, forwarders, terminals and other companies in the Transport industry, for their long term investment in containers and related equipment.'
    },
  }
];

And I parse it with this function:

const filterDataByLanguage = (data, addLang, removeLang) => {
    const arr = data.slice(0);
    let results = [];

    for (let i = 0; i < arr.length; i++) {
        delete arr[i][removeLang];
        results.push(arr[i]);
        for (key in arr[i][addLang]) {
            results[i][key] = arr[i][addLang][key]
        }
        delete arr[i][addLang];
    }
    return results;
}

I use this function to get data for to specific files, en.json and nl.json, like that:

let enData = filterDataByLanguage(fetchedServices, 'en', 'nl');
let nlData = filterDataByLanguage(fetchedServices, 'nl', 'en');

The problem is the first call is modify input array (data).

So my question is, how I can make input to return new instance when new function call is happening.

Thanks for any information.

2
  • What about modifying filterDataByLanguage so it doesn't modify the input array? Commented Jun 19, 2020 at 18:44
  • It's modify data, so the first call it's modify the data and the second call manipulate result from first call. Commented Jun 19, 2020 at 18:47

2 Answers 2

3

As a general rule, I'd recommend very rarely mutating data (only mutate in cases where you're generating the data). You could take the lazy route and do a deep clone with something like lodash, but you could instead modify the function so it doesn't mutate the inputs:

const filterDataByLanguage = (data, addLang, removeLang) => {
    return data.map(item => {
       const { [removeLang]: removed, ...remaining } = item;
       return Object.assign(remaining, item[addLang]);
    });
}
Sign up to request clarification or add additional context in comments.

3 Comments

Will {...remaining} create a copy of an object with two levels, as in the OP's example? I think you need a deepcopy to ensure immutability
I will try to use this approach to return a map and inside this to construct my new model, thank you!
@OlgaPp: it doesn't; remaining is a shallow copy. Whether you need to do a deep copy depends on if the consuming code plans to mutate or not. If you never mutate your data throughout your code base, there's no need for CPU-expensive cloning.
0

Two suggestions.

  1. Why are you even deleting elements from arr[i] if you are not returning arr, and based on your comment you don't want your arr to be modified.

  2. var copy_obj = deepcopy(arr[i]) //deepcopy using any preferred method from https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript
    
    results.push(copy_obj);
    
    for (key in arr[i][addLang]) {
    
        results[i][key] = arr[i][addLang][key]
    
    }
    

What is the most efficient way to deep clone an object in JavaScript?

1 Comment

The result is used in two different files, en and nl and the structure must be the same, ex: nl.json -> "title: "Title NL", en.json -> "title": "Title EN"

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.