Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

skipNulls option for queryString.stringify #196

Closed
goodwin64 opened this issue Jul 26, 2019 · 10 comments · Fixed by #215
Closed

skipNulls option for queryString.stringify #196

goodwin64 opened this issue Jul 26, 2019 · 10 comments · Fixed by #215

Comments

@goodwin64
Copy link

Hi!

I am now comparing 2 libs for future use on my project: qs and query-string.
The second one has some advantages like encoding/decoding booleans and numbers which are important for me. But the 1st one has skipNulls option which allows to skip null and undefined values:

const obj1 = {
  a: 1,
  b: '2',
  c: [3, 4, 5],
  d: true,
  e: 'just string',
  f: null,
  g: undefined,
};

// qs
// can skip null/undefined values
const ex2 = qs.stringify(obj1, {
  addQueryPrefix: true,
  arrayFormat: 'comma',
  skipNulls: true,
});
const ex3 = qs.parse(ex2, {
  parseArrays: true,
  comma: true,
  ignoreQueryPrefix: true,
});

// query-string
// can store numbers and booleans
const ex4 = queryString.stringify(obj1, {
  strict: true,
});
const ex5 = queryString.parse(ex4, {
  parseNumbers: true,
  parseBooleans: true,
});

console.log('ex2', ex2);
console.log('ex3', ex3);
console.log('ex4', ex4);
console.log('ex5', ex5);

Screenshot from 2019-07-26 10-48-56

Does it sound reasonable to implement this option?

@sindresorhus
Copy link
Owner

Sure, PR welcome. For the person that wants to work on this, don't forget to add docs, tests, and update the TypeScript definition.

@sindresorhus
Copy link
Owner

I think the option should be skipNullAndUndefined to make it clear what it does.

@FredrikAugust
Copy link

I'll get to work on this now.

FredrikAugust added a commit to FredrikAugust/query-string that referenced this issue Jul 29, 2019
You can now pass an option called `skipNullAndUndefined` to the options
object in stringify to prevent the generator from generating keys for
those keys.

Fixes sindresorhus#196.
@goodwin64
Copy link
Author

@sindresorhus PR is ready. Looking forward it to be merged.

@MichaelDeBoey
Copy link

@sindresorhus undefined is already skipped by default.

@ashtonian
Copy link

3 separate configurable options would be very nice inspired by https://www.npmjs.com/package/qs.

{
"skipNulls" : true|false, 
"skipUndefined": true|false, // currently default
"skipEmptyStrings":true|false
}

@sindresorhus
Copy link
Owner

@ashtonian That seems a bit over the top in configurability. You would need to present arguments for why those are needed with actual use-cases.

@ashtonian
Copy link

ashtonian commented Sep 1, 2019

@sindresorhus - ha it may be a bit over the top.

For separating undefined and nulls I would prefer this because sometimes they are used differently in the back end. I've never wanted to pass undefined, but I have wanted to pass nulls, sometimes to use it as a value, or sometimes to clear a relationship/field in an edit form submission.

For the skipEmptyStrings I'm mainly using this for search forms, via a vue hook to store search state in the query and via an axios hook to submit said search queries to an api.

// ... 
    data () {
      return {
        searchForm: {
          someFieldA:"",
          someFieldB:undefined,
          someFieldC:null
        }
      }
// ...
this.$router.replace({
  query: this.searchForm // passes "" strings around for optional fields
})
// ... 
this.axios.get("/some/api/search",{query:this.searchForm})

I have certain 3rd part input components that self parse to a respective type that is bound to my components data objects this.searchForm. Sometimes their default values specifically <b-input type="number"> from buefy will default to "" and then that gets forwarded on in place of a number and causes problems.

@mikestecker
Copy link

mikestecker commented Sep 6, 2019

Stumbled on this thread looking for the same thing. skipEmptyStrings as described above by @ashtonian is exactly what I'm looking for. I'm using the query string in a search form as well, however I'd love to see it as a parse option, this way I can just strip it out of the object if it is ""

@mikestecker
Copy link

I found a workaround, but it would be great to have this built-in

Here's my workaround:

    const routerQuery = queryString.parse(router.asPath.split(/\?/)[1], {
      parseNumbers: true,
      parseBooleans: true
    });
    const removeFalsy = obj => {
      let newObj = {};
      Object.keys(obj).forEach(prop => {
        if (obj[prop]) {
          newObj[prop] = obj[prop];
        }
      });
      return newObj;
    };

    const query = removeFalsy(routerQuery);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment