0

I am trying to turn an array of JavaScript objects into a URL string with params, as seen below:

const objects = [{
    firstName: "John",
    lastName: "Doe",
    age: 46
  },
  {
    country: "France",
    lastName: "Paris"
  }
]

let entry_arr = [];

objects.forEach(obj => {
  Object.entries(obj).forEach(entry => {
    entry_arr.push(entry.join('='));
  });
});

let entry_str = entry_arr.join('&');

console.log(entry_str);

By all appearances, the above code works. There is a problem though.

The problem

As you can see, I have 2 nested forEach loops. For better performance, I wish I knew how to avoid this nesting and instead use only one forEach loop.

How can I achieve the same result with inly one loop?

5
  • 1
    cant see how to avoid 2 loops Commented Jan 9, 2023 at 10:24
  • 2
    It is an array with objects containing multiple and different keys so you need two loops for this. If you make a structure which always have the same keys then you could do this with one loop. Commented Jan 9, 2023 at 10:28
  • 1
    Smells like Premature Optimisation. Are you calling this code frequently enough that it has a noticeable performance impact? Commented Jan 9, 2023 at 10:28
  • Note that your code fails to escape any special characters that might be in your data. Using URLSearchParams would be more robust. Commented Jan 9, 2023 at 10:32
  • You could use: new URLSearchParams(Object.assign({}, ...objects)).toString(). But, this will overwrite the duplicate parameter lastName. This will also handle special characters in values. Commented Jan 9, 2023 at 10:51

3 Answers 3

2

Merging each object inside the array in a main one would be the only solution I can think of. ( I assumed lastName: paris was a typo)

const objects = [{
    firstName: "John",
    lastName: "Doe",
    age: 46
  },
  {
    country: "France",
    city: "Paris"
  }
]

const obj = objects.reduce((acc, obj) => Object.assign(acc, obj), {});

const entry_str = Object.entries(obj).map(entry => 
    entry.join('=')
  ).join('&');

console.log(entry_str);

Sign up to request clarification or add additional context in comments.

Comments

1

The answer provided by Nina stil uses a nested loop, instead of using forEach, map is used.

For special character handling i strongly recommend to use the URLSearchParams class.

I would advise to join the array of objects in one single objects with reduce and import the entries in a URLSearchParams

const objects = [
    { firstName: "John", lastName: "Doe", age: 46 }, { country: "France", lastName: "Paris" }];
let reduced = objects.reduce((acc, object) => Object.assign(acc, object))
let params = new URLSearchParams(reduced);

console.log(reduced);
console.log(params.toString());

Comments

0

At least, you need to map the entries with joining key and value and join the nested entries and outer array.

const
    objects = [{ firstName: "John", lastName: "Doe", age: 46 }, { country: "France", lastName: "Paris" }],
    result = objects
        .map(object => Object
            .entries(object)
            .map(entry => entry.join('='))
            .join('&')
        )
        .join('&');

console.log(result);

2 Comments

There is a problem though: the ampersand character (&) is converted to %26 when I do a GET request. (I use the params as HttpParams in Angular).
i am sorry, i have no clue of angular.. maybe angular allowes to add key value pairs as parameters.

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.