1

I am attempting to create a string that is used with HTML. But the scope of what I am attempting is completed in javascript. My code is not returning the way my mentor has desired, so I am at a bit of loss.

My function is called toQueryString, which accepts an object and returns a string with each key and value separated by a = and each pair separated by a &. If the value is an array, add another pair to the string with each value.

My code is:

function toQueryString(obj) {
  var key = Object.keys(obj);
  var value = Object.values(obj);
  var result = ``;
  for (let i = 0; i < key.length; i++) {
    for (let j = 0; j < value.length; j++) {
      result += key[i] += `=` + value[j] + `&`;
    }
  }
  return result;
}

toQueryString({"bar": [ 2, 3], "foo": 1 }) // "bar=2&bar=3&foo=1"

This returns:

'bar=2,3&bar=2,3&=1&foo=2,3&foo=2,3&=1&'

but should return this:

bar=2&bar=3&foo=1

Can anyone help me figure out what is broken?

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
  • If you look at your code, you will see that you're using a double for loop, where for each key, you iterate over _every_ value. That's not what you want. You want to, for each key, process _only its own values_, so start by changing that logic. – Mike 'Pomax' Kamermans May 13 '20 at 15:53
  • Or better yet [How to create query parameters in Javascript?](https://stackoverflow.com/questions/111529/how-to-create-query-parameters-in-javascript) – Liam May 13 '20 at 15:55
  • @Liam that's... a really poor question to pick as possible duplicate. The answers are all over the place, and I don't see any that cover the unpacking that this homework assignment is asking for. – Mike 'Pomax' Kamermans May 13 '20 at 15:55
  • so @Mike'Pomax'Kamermans does this mean I will have to remove the second for loop? – Billy.Brown0618 May 13 '20 at 15:56
  • There are loads of ways in which to fix this code, but as what very much sounds like homework you're going to have to explain what artificial restrictions you've been asked to work with: can you use normal modern JS, or are you locked in "I have to use a for loop", "I have to compose a string", etc? Because if modern JS is fine, then there aren't going to be any explicit for loops at all, it'd start with `return Object.entries(input).map(...)...` and go from there. – Mike 'Pomax' Kamermans May 13 '20 at 15:57
  • @Mike'Pomax'Kamermans the assignment doesnt have any restrictions in the prompt. The only hesitation I have by saying that is my wet behind the ears-ness so nothing to complicated I removed the second for loop which did help it returned – Billy.Brown0618 May 13 '20 at 16:00
  • @Billy.Brown0618 Does my answer work for you? – Unmitigated May 13 '20 at 16:05
  • @hev1 I see what you did there and it does work. Thanks to you and Mike'Pomax'Kamermans for the assistance! Along with this link also helped me understand. Thanks everyone https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce – Billy.Brown0618 May 13 '20 at 17:00

1 Answers1

1

The problem with your code currently is that you have two layers of for loops; thus, you iterate over each value for each iteration of a key, which is erroneous.

To get the desired result, you can get all the entries of the object using Object.entries and use reduce. When the value is an array, use forEach to iterate through it and add all the values of the array to the query string; otherwise, just add the single key-value pair to the query string. "&" should be appended to the query string when a new key-value pair is to be added if the current query string is not empty.

function toQueryString(obj) {
  return Object.entries(obj).reduce((acc,[key,val])=>{
      if(Array.isArray(val)){
        val.forEach(e=>acc += (acc ? "&": "") + key + "=" + e);
      } else {
       acc += (acc ? "&": "") + key + "=" + val;
      }
      return acc;
  }, "");
}
console.log(toQueryString({"bar": [ 2, 3], "foo": 1 }));
Unmitigated
  • 76,500
  • 11
  • 62
  • 80