Next.js router create query string and query string array - reactjs

I use Next.js on my project and I need to make a dynamic query string. I use this code:
const createQuery = (filter) => {
let currentPath = router.pathname;
let filterSize = Object.keys(filter).length;
filterSize != 0 ? (currentPath += "?") : null;
Object.keys(filter).map(function (key, index) {
currentPath +=
key + "=" + filter[key] + (index === filterSize - 1 ? "" : "&");
});
router.push(currentPath);
};
It works but I don't send an array to query string. How can I do this? Also, ss there an easier way to create a query string in Next.js?

You can use URLSearchParams to simplify your code
const params = new URLSearchParams({
var1: "value",
var2: "value2",
arr: "foo",
});
console.log(params.toString());
//Prints "var1=value&var2=value2&arr=foo"

You can easily pass dynamic query strings using nextjs/router
Router.push accepts query as an object which will be converted to query parameters.
for example:
Router.push({
pathname: currentPath,
query: {
page: 1,
skip: 10
}
})
// results into currentPath?page=1&skip=10

Related

Split a JSON object by parameters

I have a JSON Object defined in Typescript, I want to split it into parts but I can only get the keys:
This is my JSON object:
let data = {
"dataTest": "data1,data2,data3",
"insTest": "ins1,ins2,ins3",
"serTest": "ser1,ser2,ser3"
}
This is what I do to loop through it:
for (let key of Object.keys(data)) {
console.log(key)
}
This is what I get:
1º //dataTest
2º //insTest
3º //serTest
This is what I want to get:
1º //dataTest: "data1,data2,data3"
2º //insTest: "ins1,ins2,ins3"
3º //serTest: "ser1,ser2,ser3"
Upgrade
Is it also possible to get the concatenation of all the values in a single array?
Example:
data1,data2,data3,ins1,ins2,ins3,ser1,ser2,ser3
Use Object.entries().
The Object.entries() method returns an array of a given object's own enumerable string-keyed property [key, value] pairs.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
const data = {
dataTest: "data1,data2,data3",
insTest: "ins1,ins2,ins3",
serTest: "ser1,ser2,ser3"
};
const entries = Object.entries(data);
entries.forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
You can get the required value using Object.entries().
let data = {
"dataTest": "data1,data2,data3",
"insTest": "ins1,ins2,ins3",
"serTest": "ser1,ser2,ser3"
}
Object.entries(data).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
Here is another way
for(let key in data) {
console.log(key + ': ' + '"' + data[key] + '"');
}
using Template literals
for(let key in data) {
console.log(`${key}: "${data[key]}"`);
}

Firebase realtime database pagination not working as expected [duplicate]

I am trying to sort orders in descending and start after on particular key but its not working
nextAfter : -Mk4-n5BnVpwhum62n2g or any Key / _id
db record:
{
'-Mk4-n5BnVpwhum62n2g': {
_id: '-Mk4-n5BnVpwhum62n2g',
createdAt: -1632171667626,
name: 'abc'
},
'-Mk40Ko9DbSeMdjIpY4': {
_id: '-Mk40Ko9DbSeMdjIpY4',
createdAt: -1632171809831,
name: 'new '
}
}
trying query :
query = dbRef.orderByChild('createdAt').startAfter(nextAfter).limitToFirst(limit);
The startAfter() method accepts two parameters - the first is the relevant orderBy value and the second is the optional key of the last entry (for when multiple entries have the same value for the orderBy criteria). So to correctly paginate the reference, you need to pass the previous entry's createdAt value and its key.
const baseQuery = dbRef
.orderByChild('createdAt')
.limitToFirst(limit);
let pageCount = 0, lastChildOnPage = undefined;
const children = [];
while (true) {
const pageQuery = pageCount === 0
? baseQuery
: baseQuery
.startAfter(lastChildOnPage.createdAt, lastChildOnPage.key);
const pageSnapshot = await pageQuery.once('value');
pageSnapshot.forEach((childSnapshot) => {
children.push({ key: childSnapshot.key, ...childSnapshot.val() });
})
const newLastChildOnPage = children[children.length-1];
if (lastChildOnPage !== newLastChildOnPage) {
lastChildOnPage = newLastChildOnPage;
pageCount++;
} else {
break; // no more data
}
}
console.log(`Grabbed ${pageCount} page(s) of data, retrieving ${children.length} children`);

query string params as array of objects - issues javascript

I've got a problem!
I need to get in query string params encode something like this:
filters[0].columnName: createdBy
filters[0].value: ew
filters[0].operation: contains
filters[1].columnName: title
filters[1].value: eweqw
filters[1].operation: endsWith
but I just get nothing but...
filters: [name,"contains", o'}]
my code is:
const getQueryStringFilters = (): string => {
let filter = filters
.reduce((acc, { columnName, value }) => {
acc.push(encodeURIComponent(`[${columnName},"contains", ${value}'}]`));
return acc;
}, [])
.join(',"and",');
if (filters.length > 1) {
filter = `[${filter}]`;
}
return filter;
};
and I am using devexpress react-grid :( cannot find solution... somebody could help me out?

react filtering an object of arrays

I'm trying to find a better way to remove value pairs of an object that contain an empty string ""
my current state is:
this.state = {
searchParams:{
query: '',
colors: [],
text: '',
legalities: '',
setName: '',
pageSize: 4
}
}
I know this won't work with my state since it isn't an array, but something like this is what i'm trying to achieve right now
var search = this.state.searchParams.filter(function (el) {
return el !== "";
});
could anyone point me in the right direction and explain a better way to do this with an object, thanks :) ?
filter only use for a array, not is a object.
You can try my code
let searchParams =
Object.keys(this.state.searchParams)
.filter( key => this.state.searchParams[key] !== '' );
this.setState({searchParams })
You can use Object.entries and Object.fromEntries.
const filteredObject = Object.fromEntries(
Object.entries(searchParams)
.filter(([key, value]) => value !== "")
);
Will create anew object with all the keys for which the value was "" removed.
You can filter it this way with reduce method. Since it is an object, you have to combine object prototype .keys with array prototype .reduce to filter it.
const searchParams = {
query: '',
colors: [],
text: '',
legalities: '',
setName: '',
pageSize: 4
}
const notEmpty = Object.keys(searchParams).reduce((nonEmptyObj, currentKey) => {
if (searchParams[currentKey] !== '') {
nonEmptyObj[currentKey] = searchParams[currentKey];
}
return nonEmptyObj;
}, {})
console.log(notEmpty);
use Object.keys. In your case like this:
var search = Object.keys(this.state.searchParams).filter(el => {
// do something
})
the most simple way is by using Object.keys method and then iterate the whole object. then check if searchParams[ele] is true and add in another object.
var newObj = {};
Object.keys(this.state.searchParams).forEach(ele => {
if (searchParams[ele]) {
newObj = { ...newObj, [ele]: searchParams[ele] };
}
});
console.log(newObj); // new object generated with empty values eliminated
this.setState({searchParams:newObj})
If you want to filter out empty strings and strings (with white spaces only) as well, then
we have trim the string and then check its length. If its string and its length is 0 after trimming, then its considered as empty and will be filtered out.
const params = this.state.searchParams
Object.keys(this.state.searchParams).filter(key =>
!(typeof params[key] === 'string' && params[key].trim().length === 0)
)
If you don't want to trim, then:
const params = this.state.searchParams
Object.keys(this.state.searchParams).filter(key => params[key] !== '')
I would highly suggest you to not to use semicolon, as it takes space and JS can now ignore semicolon as well. Also, not to use double quotes unless required.

GET with query string with Fetch in React Native

I am making a request like this:
fetch("https://api.parse.com/1/users", {
method: "GET",
headers: headers,
body: body
})
How do I pass query string parameters? Do I simply add them to the URL? I couldn't find an example in the docs.
Your first thought was right: just add them to the URL.
Remember you can use template strings (backticks) to simplify putting variables into the query.
const data = {foo:1, bar:2};
fetch(`https://api.parse.com/1/users?foo=${encodeURIComponent(data.foo)}&bar=${encodeURIComponent(data.bar)}`, {
method: "GET",
headers: headers,
})
Short answer
Just substitute values into the URL like this:
const encodedValue = encodeURIComponent(someVariable);
fetch(`https://example.com/foo?bar=${encodedValue}`);
Longer answer
Yes, you just need to add the query string to the URL yourself. You should take care to escape your query string parameters, though - don't just construct a URL like
`https://example.com/foo?bar=${someVariable}`
unless you're confident that someVariable definitely doesn't contain any &, =, or other special characters.
If you were using fetch outside of React Native, you'd have the option of encoding query string parameters using URLSearchParams. However, React Native does not support URLSearchParams. Instead, use encodeURIComponent.
For example:
const encodedValue = encodeURIComponent(someVariable);
fetch(`https://example.com/foo?bar=${encodedValue}`);
If you want to serialise an object of keys and values into a query string, you could make a utility function to do that:
function objToQueryString(obj) {
const keyValuePairs = [];
for (const key in obj) {
keyValuePairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
}
return keyValuePairs.join('&');
}
... and use it like this:
const queryString = objToQueryString({
key1: 'somevalue',
key2: someVariable,
});
fetch(`https://example.com/foo?${queryString}`);
Here's an es6 approach
const getQueryString = (queries) => {
return Object.keys(queries).reduce((result, key) => {
return [...result, `${encodeURIComponent(key)}=${encodeURIComponent(queries[key])}`]
}, []).join('&');
};
Here we're taking in a queries object in the shape of key: param
We iterate and reduce through the keys of this object, building an array of encoded query strings.
Lastly we do a join and return this attachable query string.
I did a small riff on Mark Amery's answer that will pass Airbnb's eslint definitions since many teams seem to have that requirement these days.
function objToQueryString(obj) {
const keyValuePairs = [];
for (let i = 0; i < Object.keys(obj).length; i += 1) {
keyValuePairs.push(`${encodeURIComponent(Object.keys(obj)[i])}=${encodeURIComponent(Object.values(obj)[i])}`);
}
return keyValuePairs.join('&');
}
My simple function to handle this:
/**
* Get query string
*
* #param {*} query query object (any object that Object.entries() can handle)
* #returns {string} query string
*/
function querystring(query = {}) {
// get array of key value pairs ([[k1, v1], [k2, v2]])
const qs = Object.entries(query)
// filter pairs with undefined value
.filter(pair => pair[1] !== undefined)
// encode keys and values, remove the value if it is null, but leave the key
.map(pair => pair.filter(i => i !== null).map(encodeURIComponent).join('='))
.join('&');
return qs && '?' + qs;
}
querystring({one: '##$code', two: undefined, three: null, four: 100, 'fi###ve': 'text'});
// "?one=%23%40%24code&three&four=100&fi%23%23%40ve=text"
querystring({});
// ""
querystring('one')
// "?0=o&1=n&2=e"
querystring(['one', 2, null, undefined]);
// "?0=one&1=2&2" (edited)
Yes you should, there are a few classes in JS, that can help you a handy one is https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
e.g. if you had the params in a javascript object say
let params = {one: 'one', two: 'two'}
you could say this function
let queryString = new URLSearchParams()
for(let key in params){
if(!params.hasOwnkey())continue
queryString.append(key, params[key])
}
then you can get your nicely formatted query string by saying
queryString.toString()
The accepted answer works, but if you have more params than one it doesn't generalize. I suggest the following approach, which also handles array parameters:
let route = 'http://test.url.com/offices/search';
if (method == 'GET' && params) {
const query = Object.keys(params)
.map((k) => {
if (Array.isArray(params[k])) {
return params[k]
.map((val) => `${encodeURIComponent(k)}[]=${encodeURIComponent(val)}`)
.join('&');
}
return `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`;
})
.join('&');
route += `?${query}`;
}

Resources