How to parse url and remove specific parameters - javascript

I would like to parse a url query string and filter and remove specific parameters.
Say the url is: www.test.com?id=123&location-texas&color=blue&event=new
And the query string : ?id=123&location-texas&color=blue&event=new
I would like to always remove the parameters id={} and color={}.
The url may or may not contain either id or color params.
The value of those parameters are not always the same but I always want to strip id and color from the query string.
I tried the following – I believe I am on the right track but need some assistance finishing up
const test = decodeURIComponent(qs.query).split('?')[1].split('&')
.filter(param => param !== id='123' || param !== color='blue' );
I would like to reconstruct the filtered array and make it :
www.test.com?location-texas&event=new

I think you can use replace
query.replace(/(\w+)=\w*/gi, (m, p) => {
if (p === 'id' || p === 'color') return ''
return m
})
More information about replace
Or just use URLSearchParams here

Related

How to get value of URL query parameter with dynamic name?

I need to extract the value of a query parameter in a URL, but the parameter changes on each page.
For example, I want to get the color variable, but it always changes based on the productID. In this case it is 'dwvar_2000440926_color' but for another product it will be 'dwvar_545240926_color'. _color stays consistent, so I'd like to key off that:
https://www.example.com/us/2000440926.html?dwvar_2000440926_color=02
Thanks!
Basic regular expression would work
const myURL = new URL("https://www.example.com/us/2000440926.html?dwvar_2000440926_color=02")
console.log(myURL.search.match(/_color=([^&]+)/)[1]);
// more specfic
console.log(myURL.search.match(/dwvar_\d+_color=([^&]+)/)[1]);
You should use regex. Based on the description of the URL behavior you described you could do something like this:
const url = new URL("https://www.example.com/us/2000440926.html?dwvar_2000440926_color=02");
// Now url.search contains your query parameters.
// We gonna apply the regex on it to capturing the color id
let matches = url.search.match(/dwvar_\d+_color=(\d+)/)
// `matches` now contains the captured groups
console.log(matches[1])
// log : 02
Assuming that 1) you want to do this on the client side 2) the color param always begins with dwvar as shown in your example and 3) that there is never more than one dwvar param, you can use the following javascript:
let searchParams = new URLSearchParams(document.location.search);
searchParams.forEach((param_value, param_name) => {
if (param_name.indexOf('dwvar') == 0) {
console.log(param_value)
}
})
window.location.search.slice(1).split('&').reduce((acc, it) => {
const [key, val] = it.split('=');
return {
...acc,
[key]: val,
};
}, {});

Split out props.location.search value

I'm trying to split out the values from props.location.search in React/Redux. I've successfully obtained the mixOne split however I can't seem to return the value of quantity. Here's my code:
const mixOne = props.location.search
? String(props.location.search.split("mixOne=")[1])
: "None";
const quantity = props.location.search
? Number(props.location.search.split("=")[1])
: 1;
And here's the URL that gets generated:
const addToCartHandler = () => {
props.history.push(
`/Cart/${productId}?quantity=${quantity}?mixOne=${mixOne}`
);
};
As you can see quantity returns null, when I need the value selected
props.location.search.split("=") on "?quantity=1?mixOne=Grape" would return [ '?quantity', '1?mixOne', 'Grape' ] since the next = is not until after mixOne.
There's a few different fixes here.
Your query string is invalid– a ? denotes the start of the query string. Separate parameters should be split up using & ampersand characters. It should look like this: ?quantity=1&mixOne=Grape
If you follow the standard here, you can then split it two ways: by = and then by & to get the different parameters. However, there is an easier way.
Using the new-ish URLSearchParams API, you can parse your parameters in a predictable way:
// Use the constructor with your `props.location.search`
const queryParams = new URLSearchParams(props.location.search);
// Use the getters to grab a specific value
const quantity = queryParams.get("quantity");
// Ensure it's a number for safety
const quantityNum = Number(quantity);
// ... the rest of your code here
The query is wrong. You're using double question marks. The second ? should be replaced with &.
?quantity=1&mixOne=Grape

Conditional statement within template literal concatenation?

I am making an API call like this:
posts: (ppp, page) =>
requests.get(`/wp-json/wp/v2/posts?per_page=${ppp}&page=${page}`)
I am not always going to be passing in posts per page or page though, so I would like to only concatenate those variables if they exist. I tried below but I can't seem to get the formatting down:
requests.get(`/wp-json/wp/v2/posts?`${ppp ? `'per_page='${ppp} : `''` `${page} ? `'&page=' ${page}` :''`)
Besides that your second solution contains syntax errors, it also isn't the most readable way to do that...
But why are you trying to reinvent the wheel?
You can use the URL API which is available both on the client-side and in Node.js:
posts: (ppp, page) => {
const url = new URL('/wp-json/wp/v2/posts')
if(ppp) url.searchParams.append('per_page', ppp)
if(page) url.searchParams.append('page', page)
return requests.get(url.href)
}
However, if you can't use the above solution for some reason, you can still implement a similar algorithm that works like the above solution. For example, you can use an array:
posts: (ppp, page) => {
const urlParams = []
if(ppp) urlParams.push(`per_page=${ppp}`)
if(page) urlParams.push(`page=${page}`)
return requests.get(`/wp-json/wp/v2/posts?${ urlParams.join('&') }`)
}
Or an even more flexible solution:
posts: (ppp, page) => {
const urlParams = {
per_page: ppp, //per_page=ppp
page, //page=page
//Add more here if you want
}
return requests.get(`/wp-json/wp/v2/posts?${
Object
.entries(urlParams)
.filter(([k, v]) => v) //If value is truthy
.map(e => e.join('=')) //Concatenate key and value with =
.join('&') //Concatenate key-value pairs with &
}`)
}
But, if you want to stick to you version, here's a fixed example of it:
requests.get(`/wp-json/wp/v2/posts?${ppp ? `per_page=${ppp}` : ''}${(ppp && page) ? '&' : ''}${page ? `page=${page}` : ''}`)

Find an entry in a multi-dimensional array where a part of a property matches with a given text

I have an array which contains three properties:
ID : number
Name : string
Description :string
ItemList :array<T>=[] and
ItemListCopy :array<T>=[]
Now it is bound to the ng-multiselect dropdown
Upon onFilterChange callback I am sending the search text to this callback method and trying to find all the items in ItemListCopy where Name contains the search text.
I tried the approach below:
var v = this.ItemListCopy.filter(item =>
Object.keys(item).some(k => item[k].includes(text))
)
if (v != null && v.length > 0) {
this.ItemList.length = 0;
this.ItemList= v;
}
Where text is the parameter that contains the search text.
But it gives the error item[k].includes(text) is not a method .
How can I achieve this?
Try just looking at the Name:
var v = this.ItemListCopy.filter(({ Name }) => Name.includes(text));

How do I access the XML element text using xml2js other than using underscore key?

I have a piece of XML looking like this:
<errorMessage>
<payload encoding="plain">The error message</payload>
</errorMessage>
and I use xml2js parser:
var parser = new xml2js.Parser({
explicitCharKey: false,
trim: true,
explicitRoot: true,
mergeAttrs: true
});
parser.parseString(myString, function(err, result) {
var payload = result.errorMessage.payload;
// how do I access the error message text?
var errorMessage = payload[0]['_'];
});
I need to access The error message string inside payload element. If I use _ key on the node containing the <payload> then the text is properly retrieved but using an underscore magic key for this looks suspicious.
Is this the recommended way? Are there any cleaner ways?
The xml2js options documentation says this:
attrkey (default: $): Prefix that is used to access the attributes.
charkey (default: _): Prefix that is used to access the character content.
So it looks like element._ is how you access the text content of element. If you want to name this key something other than _ (say, textContent), you can change it like this:
parseString(xml, {charkey: 'textContent'}, function(err, result) {
// result.element.textContent will hold the text value of result.element
});
However, I have not found a way to make the text content always available from the _ key. For example, this:
xml2js.parseString(
'<element>1.23</element>', // <-- notice that this has no attributes
function(err, result) {
console.log(JSON.stringify(result));
}
);
outputs this:
{"element":"1.23"}
But if you change the XML to add an attribute, like <element attr="value">1.23</element>, you get this:
{"element":{"_":"1.23","$":{"attr":"value"}}}
I need to parse XML output which sometimes has attributes but sometimes does not. There may be a better way, but when I need the text from an element, I just call getText(element), where getText is:
var getText = function(elt) {
if (typeof(elt) === 'string') return elt;
if (typeof(elt) === 'object' && elt.hasOwnProperty('_')) return elt._;
return ''; // or whatever makes sense for your case
}
If you parse an XML doc with attributes, you'll get that funny underscore in your JSON results. It is what it is. If you really hate that and don't want any of the attributes in your doc, set the ignoreAttrs : true in your options block. Then you'll access the element text right from the element's property.
you can do this
const { transform } = require('camaro')
;(async function() {
const xml = `
<errorMessage>
<payload encoding="plain">The error message</payload>
</errorMessage>
`
const { errorMessage } = await transform(xml, {
errorMessage: 'errorMessage/payload'
})
console.log(errorMessage)
})()
You can also just set mergeAttrs to true to get rid of all the $ attribute keys:
mergeAttrs (default: false): Merge attributes and child elements as properties of the parent, instead of keying attributes off a child attribute object. This option is ignored if ignoreAttrs is true.
See https://www.npmjs.com/package/xml2js#options

Categories