Split out props.location.search value - javascript

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

Related

Assign values from one set of key/value pairs to keys of another?

I'm working with the outputs of an Intranet I don't control.
I have this string:
let template = 'LAWYER=|FIRM=|SUIT_DESCRIPTION=|DEF_COMMENT=|PLF_COMMENT=|';
It goes on longer, but that's the pattern.
Now there's another similar string, but with data assigned, as in this example:
let current= 'FIRM=Smith and Wesson LLP|SUIT_DESCRIPTION=It\'s a royal mess|PLF_COMMENT=some freeform text|LAWYER=Bob Smith';
Now, notice that not every element in template is necessarily represented in current, and the order may be different (if the latter fact is a big deal, I can ensure the order is the same).
What I'm trying to do, is take every element that is in current, and populate the matching element in template, if it exists. (or, alternatively and potentially preferred, insert every non-matching element in template into current, but ideally in the same order as template).
Using the date above, the result I'm looking for is:
result = 'LAWYER=Bob Smith|FIRM=Smith and Wesson LLP|SUIT_DESCRIPTION=It\'s a royal mess|DEF_COMMENT=|PLF_COMMENT=some freeform text|';
I'm not very accomplished with JavaScript :(
I tried various things in JSFiddle using split() and match() but I just made a mess of it.
// Convert the template to an array of keys
const getKeys = str => str.split('|').map(entry => entry.split('=')[0]);
// Convert the data to an object
const toObj = str => Object.fromEntries(str.split('|').map(entry => entry.split('=')));
// Reconcile the data with the template
const compile = (templateStr, dataStr) => {
const keys = getKeys(templateStr);
const data = toObj(dataStr);
return keys.reduce((results, key) => {
if(key) results.push([key, data[key] ?? '']);
return results;
}, []);
};
// Convert the results back into a string
const toString = data => data.map(entry => entry.join('=')).join('|') + '|';
// And then a test
let template = 'LAWYER=|FIRM=|SUIT_DESCRIPTION=|DEF_COMMENT=|PLF_COMMENT=|';
let current = 'FIRM=Smith and Wesson LLP|SUIT_DESCRIPTION=It\'s a royal mess|PLF_COMMENT=some freeform text|LAWYER=Bob Smith';
console.log(toString(compile(template, current)));

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,
};
}, {});

Check if two URL strings are equal

I'm building out a function to handle dynamic phone number swapping, identifying the referral url, mapping through a data set, and then outputting the promoUrl's related phone number. The data is formatted like this:
const phoneNumbers = [
{
promoUrl: '/interior-doors/',
promoNumber: '589-918-0710',
},
{
promoUrl: '/promo4/',
promoNumber: '307-789-8615',
},
];
And the function maps through the data and reduces it, allowing me to sort through it like this:
const url = location.pathname.replace(/\/+$/, '');
const promoNumber = phoneNumbers.reduce((promoNumber, results) => {
const hasPromo = results.promoUrl.includes(url);
if (hasPromo) {
return results.promoNumber;
}
return promoNumber;
}, '');
I'm having some issues with hasPromo. The way it's built right now allows for the promoUrl to have some variance and still work, meaning as long as it includes what is returned from url then it works i.e. /interior-doors/, /interior-doors, and interior-doors will all work, which is great, but it also works if url is /interior-do. I need it to not do that. It should work independent of formatting, but only return the promoNumber if the string of letters is exact.
I'm assuming this is a regex thing, but I don't know what I'm doing with regex. Any help would be greatly appreciated.
Use == to do an exact match. And since the promoURL property always has / around it, add those delimiters when you set url
const url = '/' + location.pathname.replace(/\/+$/, '') + '/';
const promoNumber = phoneNumbers.reduce((promoNumber, results) => {
const hasPromo = results.promoUrl == url;
if (hasPromo) {
return results.promoNumber;
}
return promoNumber;
}, '');
reduce also seems like the wrong function for this. You just need to find the matching promoUrl, you don't have to continue reducing, since the reduction function doesn't merge the results in any way.
const promo = phoneNumbers.find(({promoUrl}) => promoUrl == url);
const promoNumber = promo ? promo.promoNumber : '';

MongoDB find method with variables

Trying to search through my mongoDB database using variable names not by specifying the exact search. Is it possible to do this? No matter how i try to format the variable I can't get a successful search. I'm trying to do something like the bottom line below
let url3 = 'http://cs544.io/11jgry2';
const ret = await dbTable.find({"shortUrl" : "http://cs544.io/11jgry2"}); //Works
const ret = await dbTable.find({"shortUrl" : url3}); //Doesn't work
Use $eq it Specifies equality condition. The $eq operator matches documents where the value of a field equals the specified value.
Check this this for further explanation and examples
Theoretically, it should work,
But I suggest having a look into using $eq instead.
Here is an example
const ret = await dbTable.find( { shortUrl: { $eq: url3 } } );

Firebase real time database compound query combining text and date

I'm trying to make a compound query (combining two children). What I want to do is fetch objects that are older than 5 minutes AND also are of a type.
So I've combined the children type and date into a new child called type_date and I do my query like this:
const now = Date.now();
const fiveMinutesMs = 5*60*1000;
const fiveMinutesAgo = now - fiveMinutesMs;
const fiveMinutesAgoQuery = "type_" + fiveMinutesAgo;
ref.orderByChild('type_date').endAt(fiveMinutesAgoQuery).once('value');
Only thing is that it doesn't work. It's giving me results of objects which doesn't even have the type_date child.
Try startAt instead of endAt. I hope it works.
EDIT: Oops I was too quick.... it works only if I'm only filtering on the date string but not together with the prepended type which I want...
So this works:
const fiveMinutesAgoIso = new Date(fiveMinutesAgo).toISOString();
const fiveMinutesAgoQuery = String(fiveMinutesAgoIso);
But not:
const fiveMinutesAgoIso = new Date(fiveMinutesAgo).toISOString();
const fiveMinutesAgoQuery = "type_" + fiveMinutesAgoIso;
Just make a Compound queries as doc says :
const fiveMinutesAgoIso = new Date(fiveMinutesAgo).toISOString();
ref.where("type", "==", TYPE_YOU_WANT).orderByChild('type').endAt(fiveMinutesAgoQuery).once('value');

Categories