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

pick method returns the first match from a filter #344

Open
shehabadel opened this issue Aug 13, 2022 · 2 comments
Open

pick method returns the first match from a filter #344

shehabadel opened this issue Aug 13, 2022 · 2 comments

Comments

@shehabadel
Copy link

shehabadel commented Aug 13, 2022

I am trying to clean a URL and only keep some parameters that I need in order to parse them
so I was using pick method providing it the url, and the filter which is a regex test method
here I am testing to check if the key in the query parameter matches the regular expression

const groupRegex = new RegExp('^(GRP_)[a-zA-Z0-9/-]','g');
export const parseGroups= (url:string)=>{
    let pickedURL = qs.pick(url,(key,value)=>groupRegex.test(key));
    console.log(pickedURL);
}
var url=`http://localhost:3000/tat?GRP_Bob[]=SW&GRP_sa[]=QW&GRP_sa[]=AA&projects[]=MP,PM&releases[]=2021.4,2022.1`
parseGroups(url)

for example http://localhost:3000/tat?GRP_Bob[]=SW&GRP_sa[]=QW&GRP_sa[]=AA&projects[]=MP,PM&releases[]=2021.4,2022.1
it should return http://localhost:3000/tat?GRP_Bob=SW&GRP_sa=QW&GRP_sa=AA
yet it only tests for the first request parameter only and logs
http://localhost:3000/tat?GRP_Bob%5B%5D=SW

I am trying to clean the url from any other parameters that doesn't match my regular expression
so I can parse the URL and extract the object
so it can be like this for example

{
       GRP_Bob:["SW"],
       GRP_sa:["QW","AA"]
 }

Instead of having other parameters parsed also which are not necessary. I know I can just parse the url normally, and then loop on the returned query object, and remove any key that doesn't match the regex, but is there anything wrong I am doing in the above snippet?

UPDATE:
I changed the filter function to be (key,value)=>key.startsWith('GRP_'))

export const parseGroups= (url:string)=>{
    let pickedURL = qs.pick(url,(key,value)=>key.startsWith('GRP_'));
    console.log(pickedURL);
    let parsedURL = qs.parseUrl(pickedURL)
    console.log(parsedURL.query)
}
var url=`http://localhost:3000/tat?GRP_Bob[]=SW&GRP_sa[]=QW&GRP_sa[]=AA&projects[]=MP,PM&releases[]=2021.4,2022.1`
parseGroups(url)

and the pickedURL logged this http://localhost:3000/tat?GRP_Bob%5B%5D=SW&GRP_sa%5B%5D=QW&GRP_sa%5B%5D=AA which is likely to be correct.
it came out like that

GRP_Bob[]: "SW"
GRP_sa[]: (2) ['QW', 'AA']

So I am confused actually what's going on with the regular expression approach, and why the keys in the second approach have [] in it?

@shehabadel
Copy link
Author

After asking on StackOverflow, thanks to Adam Thomas for solving the regular expression approach.

Ah yeh! This one is a rare gotcha and totally unexpected every time I see it.
RegExp actually has state. See Why does JavaScript's RegExp maintain state between calls? and Why does Javascript's regex.exec() not always return the same value?.
In your case, you don't need the g flag, so removing that should also fix your problem since that makes the regex stateless.

So here is the code snippet now

const groupRegex = new RegExp('^(GRP_)[a-zA-Z0-9/-]');
export const parseGroups= (url:string)=>{
    let pickedURL = qs.pick(url,(key,value)=>groupRegex.test(key));
    console.log(pickedURL);
    let parsedURL = qs.parseUrl(pickedURL)
    console.log(parsedURL.query)        
}
var url=`http://localhost:3000/tat?GRP_Bob[]=SW&GRP_sa[]=QW&GRP_sa[]=AA&projects[]=MP,PM&releases[]=2021.4,2022.1`
parseGroups(url)

pickedUrl logs like this, which I don't really understand why [] was changed to %5B%5D
http://localhost:3000/tat?GRP_Bob%5B%5D=SW&GRP_sa%5B%5D=QW%2CAA
while parsedURL logs like this, which I believe was affected since the keys have [] characters in it.
{GRP_Bob[]: 'SW', GRP_sa[]: 'QW,AA'}

@shehabadel
Copy link
Author

Well I partially solved it by passing the following options argument

let parsedURL = qs.parseUrl(url,{arrayFormat: 'bracket-separator', arrayFormatSeparator:','})

I still have no idea why pick method converts [] to %5B5D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant