Query-string encoding of a Javascript Object
like this?
serialize = function(obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
}
console.log(serialize({
foo: "hi there",
bar: "100%"
}));
// foo=hi%20there&bar=100%25
Query-string encoding of a Javascript Object
like this?
serialize = function(obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
}
console.log(serialize({
foo: "hi there",
bar: "100%"
}));
// foo=hi%20there&bar=100%25
Javascript: recursively encode and decode querystring. (object to querystring, querystring to object)
I think, what you want to do, is encode and decode nested objects.
There is no single standard, but very often, QS (Query String) syntax is used:
{
"attribute": "value",
"array": ["apples", "bananas"],
"object": { "number": 55 },
}
will become:
?attribute=value&array[0]=apples&array[1]=bananas&object[number]=55
Example code:
function decode(querystring: string): object {
function parseValue(value: string): any {
if (value === 'TRUE') return true;
if (value === 'FALSE') return false;
return isNaN(Number(value)) ? value : Number(value);
}
function dec(list: any[], isArray = false): object {
let obj: any = isArray ? [] : {};
let recs: any[] = list.filter((item) => {
if (item.keys.length > 1) return true;
obj[item.keys[0]] = parseValue(item.value);
});
let attrs = {};
recs.map((item) => {
item.key = item.keys.shift();
attrs[item.key] = [];
return item;
}).forEach((item) => attrs[item.key].push(item));
Object.keys(attrs).forEach((attr) => {
let nextKey = attrs[attr][0].keys[0];
obj[attr] = dec(attrs[attr], typeof nextKey === 'number');
});
return obj;
}
return dec(
querystring
.split('&')
.map((item) => item.split('=').map((x) => decodeURIComponent(x)))
.map((item) => {
return {
keys: item[0]
.split(/[\[\]]/g)
.filter((n) => n)
.map((key) => (isNaN(Number(key)) ? key : Number(key))),
value: item[1],
};
})
);
}
export function encode(object: object): string {
function reducer(obj, parentPrefix = null) {
return function (prev, key) {
const val = obj[key];
key = encodeURIComponent(key);
const prefix = parentPrefix ? `${parentPrefix}[${key}]` : key;
if (val == null || typeof val === 'function') {
prev.push(`${prefix}=`);
return prev;
}
if (typeof val === 'boolean') {
prev.push(`${prefix}=${val.toString().toUpperCase()}`);
return prev;
}
if (['number', 'string'].includes(typeof val)) {
prev.push(`${prefix}=${encodeURIComponent(val)}`);
return prev;
}
prev.push(
Object.keys(val).reduce(reducer(val, prefix), []).join('&')
);
return prev;
};
}
return Object.keys(object).reduce(reducer(object), []).join('&');
}
Encode object literal as URL query string in Javascript
I have made a quick function for you which should achieve this for you, it will create parameters from your key=>value pairs and stringify your non primitive values.
var objToParams = function(obj){
var paramString = '';
for (var key in data) {
var value = obj[key];
if(obj[key] instanceof Array || obj[key] instanceof Object){
value = encodeURIComponent(JSON.stringify(value));
}
if (paramString != "") paramString += "&";
paramString += key + "=" + encodeURIComponent(value);
}
return paramString;
}
var data = {"apple": [{"kiwi": "orange"}, {"banana": "lemon"}], "pear": "passion fruit"};
console.log(objToParams(data));
http://jsfiddle.net/7buy3rjy/
Edit, from your comment this should work and is now matching the output of $.param:
http://jsfiddle.net/mg511z7w/
var data = {"apple": [{"kiwi": "orange"}, {"banana": "lemon"}], "pear": "passion fruit"};
var stringifyParam = function(data, topLevel, keyProp) {
var string = '';
for (var key in data) {
if(keyProp && topLevel[keyProp] ) {
if ( (topLevel[keyProp] instanceof Array&&topLevel[keyProp].indexOf(data[key])!==0) ) {
string += keyProp;
} else if ( (topLevel[keyProp] instanceof Object&&topLevel[keyProp][key]) ) {
string += keyProp;
}
}
if (typeof(topLevel[key])=='undefined') {
string += '[' + key + ']';
}
if (data[key] instanceof Array) {
string += stringifyParam(data[key], topLevel, key);
} else if(data[key] instanceof Object){
string += stringifyParam(data[key], topLevel, key);
} else {
if (typeof(topLevel[key])!='undefined') {
string += key;
}
string += '=' + data[key];
string += '&';
}
}
return string;
},
toParam = function(data){
var string = stringifyParam(data,data);
return encodeURI(string.substring(0,string.length-1).split(' ').join('+'));
};
console.log(toParam(data)); //apple%5B0%5D%5Bkiwi%5D=orange&apple%5B1%5D%5Bbanana%5D=lemon&pear=passion+fruit
console.log($.param(data)); //apple%5B0%5D%5Bkiwi%5D=orange&apple%5B1%5D%5Bbanana%5D=lemon&pear=passion+fruit
How to encode and parse / decode a nested query string Javascript
So, the qs library proved to be my savior after all. I just wasn't implementing it correctly before. So, with the same form data structure, just make sure to import qs to your form component file:
import qs from 'qs'
and then make your encode function nice and succinct with:
// Transforms the form data from the React Hook Form output to a format Netlify can read
const encode = (data) => {
return qs.stringify(data)
}
Next, use this encode function in your handle submit function for the form:
// Handles the post process to Netlify so we can access their serverless functions
const handlePost = (formData, event) => {
event.preventDefault()
fetch(`/`, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: encode({ "form-name": 'add-registration-form', ...formData }),
})
.then((response) => {
reset()
if(response.status === 200) {
alert("SUCCESS!")
} else {
alert("ERROR!")
}
console.log(response)
})
.catch((error) => {
console.log(error)
})
}
Finally, this is what your Netlify submission-created.js file should look like more or less:
const sanityClient = require("@sanity/client")
const client = sanityClient({
projectId: process.env.GATSBY_SANITY_PROJECT_ID,
dataset: process.env.GATSBY_SANITY_DATASET,
token: process.env.SANITY_FORM_SUBMIT_TOKEN,
useCDN: false,
})
const qs = require('qs')
const { nanoid } = require('nanoid');
exports.handler = async function (event, context, callback) {
// Pulling out the payload from the body
const { payload } = JSON.parse(event.body)
// Checking which form has been submitted
const isAddRegistrationForm = payload.data.formId === "add-registration-form"
// Build the document JSON and submit it to SANITY
if (isAddRegistrationForm) {
const parsedData = qs.parse(payload.data)
let schedule = parsedData.days
.map(d => (
{
_key: nanoid(),
_type: "classDayTime",
day: d.day,
time: {
_type: "timeRange",
start: d.start,
end: d.end
}
}
))
const addRegistrationForm = {
_type: "addRegistrationForm",
submitDate: new Date().toISOString(),
_studentId: parsedData._id,
classType: parsedData.classType,
schedule: schedule,
language: parsedData.language,
classSize: parsedData.size,
}
const result = await client.create(addRegistrationForm).catch((err) => console.log(err))
}
callback(null, {
statusCode: 200,
})
}
How to convert from object to query string in javascript
It would be much easier if you would use objects as intended but:
const obj = {
param1: 'test',
param2: 'true',
param3: 'test2',
param4: 'NO',
}
const entries = Object.values(obj)
const trueObj = {}
for (let i = 0; i < entries.length; i += 2) {
trueObj[entries[i]] = entries[i + 1]
}
const params = new URLSearchParams(trueObj)
const queryString = params.toString()
console.log(queryString)
Query-string encoding of a Javascript Object
like this?
serialize = function(obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
}
console.log(serialize({
foo: "hi there",
bar: "100%"
}));
// foo=hi%20there&bar=100%25
Encode URL in JavaScript?
Check out the built-in function encodeURIComponent(str) and encodeURI(str).
In your case, this should work:
var myOtherUrl =
"http://example.com/index.html?url=" + encodeURIComponent(myUrl);
Related Topics
When Should I Use Curly Braces For Es6 Import
Create and Save a File With JavaScript
How to Display a JavaScript Object
How to Force Js to Do Math Instead of Putting Two Strings Together
Pass Variables by Reference in JavaScript
How to Empty an Array in JavaScript
Listening For Variable Changes in JavaScript
How to Access React Instance (This) Inside Event Handler
Difference Between a Function Expression VS Declaration in JavaScript
Is It Bad Practice to Have a Constructor Function Return a Promise
Getting the Client'S Time Zone (And Offset) in JavaScript
How to Check If an Object Is an Array
How to Loop Through a Plain JavaScript Object With the Objects as Members
Async Function Returning Promise, Instead of Value
How to Execute a JavaScript Function When I Have Its Name as a String
Can Scrapy Be Used to Scrape Dynamic Content from Websites That Are Using Ajax