karl
karl

Reputation: 331

Using object destructuring instead of default parameters for my api calls

I'm trying to use object destructuring instead of default parameters for my api calls in my vue component. Can someone tell me why this would not work? They are both methods in my component, the caps lock variables are set outside the component and the this ones are pulled from data.

buildUrl() {
  const options = {
    parm1: PARM_1,
    parm2: PARM_2,
    parm3: this.parm3,
    parm4: this.parm4
  };
  const { parm1, parm2, parm3, parm4 } = options;
  return `things?parm1=${parm1}&parm2=${parm2}&parm3=${parm3}&parm4=${parm4}`;
}

async foo() {
  const { parm1, items: things } = await this.$axios.$get(
    this.buildUrl({ parm1: this.parm1 + 1 })
  );
  this.parm1 = parm1;
  this.things.push(...things);
},

Upvotes: 2

Views: 340

Answers (3)

nirazul
nirazul

Reputation: 3955

It looks like you don't accept any parameters in the buildUrl function. But in foo you're passing an object to buildUrl.

On a side note, to handle mass url query params, it's easier to use the new and shiny URLSearchParams API if browser support allows it (that means: no IE).

So change your code to:

buildUrl({ 
  parm1 = PARM_1, 
  parm2 = PARM_2, 
  parm3 = this.parm3, 
  parm4 = this.parm4 
}) {
  const params = new URLSearchParams({ parm1, parm2, parm3, parm4 });
  return `things${params}`;
}

Upvotes: 2

Tirzono
Tirzono

Reputation: 436

What I think what you want is something like this:

buildUrl({
  parm1 = PARM_1,
  parm2 = PARM_2,
  parm3 = this.parm3,
  parm4 = this.parm4
}) {
  return `things?parm1=${parm1}&parm2=${parm2}&parm3=${parm3}&parm4=${parm4}`;
}

async foo() {
  const { parm1, items: things } = await this.$axios.$get(
    this.buildUrl({ parm1: this.parm1 + 1 })
  );
  this.parm1 = parm1;
  this.things.push(...things);
},

Which means parm1 defaults to PARM_1, parm2 defaults to PARM_2, parm3 defaults to this.parm3 and parm4 defaults to this.parm4.

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074335

You're not accepting any parameters at all in buildUrl. It looks like you want to accept a single parameter that you destructure and provide various defaults for. That looks like this:

buildUrl({parm1 = PARM_1, parm2 = PARM_2, parm3: this.parm3, parm4: this.parm4} = {}) {
  return `things?parm1=${parm1}&parm2=${parm2}&parm3=${parm3}&parm4=${parm4}`;
}

Or with more line breaks:

buildUrl({
    parm1 = PARM_1,
    parm2 = PARM_2,
    parm3: this.parm3,
    parm4: this.parm4
} = {}) {
  return `things?parm1=${parm1}&parm2=${parm2}&parm3=${parm3}&parm4=${parm4}`;
}

This part is the destructuring:

{parm1 = PARM_1, parm2 = PARM_2, parm3: this.parm3, parm4: this.parm4}

...which handles providing defaults for any properties not supplied by the caller.

This part makes the entire parameter optional by providing a default value for it:

= {}

That makes buildUrl() work, using all defaults. (The overall anonymous parameter is defaulted to {}, then all of the destructured parameters get their defaults because {} doesn't have properties for them.) Without this overall default, you'd need to use buildUrl({}) instead.


Side note: Query parameters (both name and value) must be URI-encoded. Your code isn't doing that. The names of your parameters don't have any characters that need encoding, so you can skip those (but you could do them in case you change them later), but the values presumably vary and need encoding.

buildUrl({
    parm1 = PARM_1,
    parm2 = PARM_2,
    parm3: this.parm3,
    parm4: this.parm4
} = {}) {
  // Ensures order (on up-to-date JavaScript engines) and gives us an object to use
  const params = {parm1, parm2, parm3, parm4};
  return "things?" + Object.entries(params).map(([key, value]) => `encodeURIComponent(key)=encodeURIComponent(value)`).join("&");
}

(Yes, order is really guaranteed there provided none of the parameter names is all digits. This was partially guaranteed by ES2015, and now ES2020 extends that to Object.entries and others because that's what all major JavaScript engines do anyway.)

Or of course:

buildUrl({
    parm1 = PARM_1,
    parm2 = PARM_2,
    parm3: this.parm3,
    parm4: this.parm4
} = {}) {
  return "things" +
    `?parm1=${encodeURIComponent(parm1)}` +
    `&parm2=${encodeURIComponent(parm2)}` +
    `&parm3=${encodeURIComponent(parm3)}` +
    `&parm4=${encodeURIComponent(parm4)}`;
}

Or use URLSearchParams as nirazul shows you.

Upvotes: 0

Related Questions