how to get the querystring from a parent page? - javascript

i am using an iframe ipage in my parentpage. I would like to get the querystring in javascript of the parentpage?

I suggest to you to use my favourite function:
function getQueryString() {
var queryStringKeyValue = window.parent.location.search.replace('?', '').split('&');
var qsJsonObject = {};
if (queryStringKeyValue != '') {
for (i = 0; i < queryStringKeyValue.length; i++) {
qsJsonObject[queryStringKeyValue[i].split('=')[0]] = queryStringKeyValue[i].split('=')[1];
}
}
return qsJsonObject;
}
Just call it from the child window like this and act with the query string as an object.
For example if you have the query string ?name=stack and you want to get it, try:
getQueryString().name
This will return stack.

nice answer from #Marawan. - if it helps anyone...
I extended this to choose the target as a parameter (self / parent)
function getQueryString(target) {
if ( target == 'parent' ) {
var queryStringKeyValue = window.parent.location.search.replace('?', '').split('&');
}
else {
var queryStringKeyValue = window.location.search.replace('?', '').split('&');
}
var qsJsonObject = {};
if (queryStringKeyValue != '') {
for (i = 0; i < queryStringKeyValue.length; i++) {
qsJsonObject[queryStringKeyValue[i].split('=')[0]] = queryStringKeyValue[i].split('=')[1];
}
}
return qsJsonObject;
}
eg.
getQueryString('parent').id; // get iframe parent url ?id=foo
getQueryString().id; // get this url ?id=foo

ES6 implementation:
export const getQueryParameters = () => {
const queryStringKeyValue = window.parent.location.search.replace('?', '').split('&');
return queryStringKeyValue.reduce((acc, curr) => {
const [key,value] = curr.split('=')
return {
...acc,
[key]: value
}
}, {})
}
Usage:
getQueryParameters().name

Related

Swap javascript object index by name

My javascript object looks like the example below, I am wondering how I should write a swap function to change the element position in the object. For example, I want to swap two elements from position 1 to 2 and 2 to 1.
{
element_name_1 : {
//.. data
}
element_name_2 : {
//.. data
}
element_name_3 : {
//.. data
}
element_name_4 : {
//.. data
}
}
Now I want to swap element_name_2 with element_name_1.
As Miles points out, your code is probably broken and should use an array. I wouldn't use it, nor is it tested, but it is possible.
var data = {
element_name_1: {},
element_name_2: {},
element_name_3: {},
element_name_4: {}
}
console.log(data);
var swap = function(object, key1, key2) {
// Get index of the properties
var pos1 = Object.keys(object).findIndex(x => {
return x === key1
});
var pos2 = Object.keys(object).findIndex(x => {
return x === key2
});
// Create new object linearly with the properties swapped
var newObject = {};
Object.keys(data).forEach((key, idx) => {
if (idx === pos1)
newObject[key2] = object[key2];
else if (idx === pos2)
newObject[key1] = object[key1];
else
newObject[key] = object[key];
});
return newObject;
}
console.log(swap(data, "element_name_1", "element_name_2"));
Have a look at the code, may this solve the problem
function swapFunction(source, destination) {
var tempValu,
sourceIndex;
for ( i = 0; i < Arry.length; i++) {
for (var key in Arry[i]) {
Ti.API.info('key : ' + key);
if (source == key) {
tempValu = Arry[i];
sourceIndex = i;
}
if (destination == key) {
Arry[sourceIndex] = Arry[i];
Arry[i] = tempValu;
return Arry;
}
}
}
}
JSON.stringify(swapFunction("key_1", "key_3")); // [{"key_3":"value_3"},{"key_2":"value_2"},{"key_1":"value_1"},{"key_4":"value_4"},{"key_5":"value_5"}]
Let me know if this works.
Good Luck & Cheers
Ashish Sebastian

Extend Javascript Syntax to Add Typing

I'd like to extend javascript to add custom type checking.
e.g.
function test(welcome:string, num:integer:non-zero) {
console.log(welcome + num)
}
which would compile into:
function test(welcome, num) {
if(Object.prototype.toString.call(welcome) !== "[object String]") {
throw new Error('welcome must be a string')
}
if (!Number.isInteger(num)) {
throw new Error('num must be an integer')
}
console.log(welcome + num)
}
What's the most straightforward way of doing this?
So far i've looked at:
sweet.js (online documentation looks out of date as I think it's going through some sort of internal rewrite)
esprima and escodegen (not sure where to start)
manually parsing using regular expressons
After evaluating all the various options, using sweet.js appears to be the best solution. It's still fairly difficult to get working (and I am probably doing stuff the wrong way) but just in case someone want's to do something similar this here was my solution.
'use strict'
syntax function = function(ctx) {
let funcName = ctx.next().value;
let funcParams = ctx.next().value;
let funcBody = ctx.next().value;
//produce the normal params array
var normalParams = produceNormalParams(funcParams)
//produce the checks
var paramChecks = produceParamChecks(funcParams)
//produce the original funcBody code
//put them together as the final result
var params = ctx.contextify(funcParams)
var paramsArray = []
for (let stx of params) {
paramsArray.push(stx)
}
var inner = #``
var innerStuff = ctx.contextify(funcBody)
for (let item of innerStuff) {
inner = inner.concat(#`${item}`)
}
var result = #`function ${funcName} ${normalParams} {
${paramChecks}
${inner}
}`
return result
function extractParamsAndParamChecks(paramsToken) {
var paramsContext = ctx.contextify(paramsToken)
//extracts the actual parameters
var paramsArray = []
var i = 0;
var firstItembyComma = true
for (let paramItem of paramsContext) {
if (firstItembyComma) {
paramsArray.push({
param: paramItem,
checks: []
})
firstItembyComma = false
}
if (paramItem.value.token.value === ',') {
firstItembyComma = true
i++
} else {
paramsArray[i].checks.push(paramItem.value.token.value)
}
}
for (var i = 0; i < paramsArray.length; i++) {
var checks = paramsArray[i].checks.join('').split(':')
checks.splice(0, 1)
paramsArray[i].checks = checks
}
return paramsArray
}
function produceNormalParams(paramsToken) {
var paramsArray = extractParamsAndParamChecks(paramsToken)
//Produces the final params #string
var inner = #``
var first = true
for (let item of paramsArray) {
if (first === true) {
inner = inner.concat(#`${item.param}`)
} else {
inner = inner.concat(#`,${item.param}`)
}
}
return #`(${inner})`
}
function produceParamChecks(paramsToken) {
var paramsArray = extractParamsAndParamChecks(paramsToken)
var result = #``
for (let paramObject of paramsArray) {
var tests = produceChecks(paramObject)
result = result.concat(#`${tests}`)
}
return result
}
function produceChecks(paramObject) {
var paramToken = paramObject.param
var itemType = paramObject.checks[0]
var checks = paramObject.checks
if (itemType === undefined) return #``
if (itemType === 'array') {
return #`if (Object.prototype.toString.call(${paramToken}) !== "[object Array]") throw new Error('Must be array:' + ${paramToken})`
else {
throw new Error('item type not recognised: ' + itemType)
}
}
}

Getting nested obj value

Given the following obj:
var inputMapping = {
nonNestedItem: "someItem here",
sections: {
general: "Some general section information"
}
};
I'm writing a function to get that data by passing in a string "nonNestedItem" or in the nested case "sections.general". I'm having to use an eval and I was wondering if there was maybe a better way to do this.
Here is what I have so far and it works okay. But improve!
function getNode(name) {
var n = name.split(".");
if (n.length === 1) {
n = name[0];
} else {
var isValid = true,
evalStr = 'inputMapping';
for (var i=0;i<n.length;i++) {
evalStr += '["'+ n[i] +'"]';
if (eval(evalStr) === undefined) {
isValid = false;
break;
}
}
if (isValid) {
// Do something like return the value
}
}
}
Linky to Jsbin
You can use Array.prototype.reduce function like this
var accessString = "sections.general";
console.log(accessString.split(".").reduce(function(previous, current) {
return previous[current];
}, inputMapping));
Output
Some general section information
If your environment doesn't support reduce, you can use this recursive version
function getNestedItem(currentObject, listOfKeys) {
if (listOfKeys.length === 0 || !currentObject) {
return currentObject;
}
return getNestedItem(currentObject[listOfKeys[0]], listOfKeys.slice(1));
}
console.log(getNestedItem(inputMapping, "sections.general".split(".")));
You don't need to use eval() here. You can just use [] to get values from an object. Use a temp object to hold the current value, then update it each time you need the next key.
function getNode(mapping, name) {
var n = name.split(".");
if (n.length === 1) {
return mapping[name];
} else {
var tmp = mapping;
for (var i = 0; i < n.length; i++) {
tmp = tmp[n[i]];
}
return tmp;
}
}

How to put and get the value by the key using object in JavaScript?

How to use the functionality of dictionary in JavaScript?
Look at this question the specified way is working, but I am setting the function instance as a key like this:
Scale = function ()
{
this.Collections = {};
this.IndexTracker = {};
this.UpdateIndex = function ()
{
var index = 0;
for ( var i = 0; i < this.Collections.length; i++ )
{
this.SetIndex( this.Collections[i], index++ );
}
}
this.SetIndex = function ( obj, value )
{
this.IndexTracker[obj] = value;
}
this.GetIndex = function ( obj, value )
{
return this.IndexTracker[obj];
    }
}
this.Collections will hold the some function instance.
The problem here is the function instance is overwritten by the next function instance in this.Collections. The the length of the Collections always is 1. How to solve this?
This is an example:
var Scale = function () {
var _Collections = {},
_IndexTracker = {},
ret = function () {
function UpdateIndex() {
var index = 0,i,l;
for (i = 0,l=_Collections.length; i < l; i++) {
this.SetIndex(_Collections[i], index++);
}
}
function SetIndex(obj, value) {
_IndexTracker[obj] = value;
}
function GetIndex(obj, value) {
return _IndexTracker[obj];
}
return {
UpdateIndex : UpdateIndex,
SetIndex : SetIndex,
GetIndex : GetIndex
};
};
return ret;
}();

what's a proper way to check for null/empty string in js before including to params?

I am building a querystring and want to exclude keys if vals are empty, what's a proper way?
setQueryString: function () {
var keyword = $('#keyword').val();
//how to exclude it if keyword is empty?
var params = {
"keyword": $.trim(keyword)
};
return params;
}
take into account, that I will have 20+ inputs like keyword..trying to avoid lots of IF statements
If you have multiple params and you don't want lots of if statements:
setQueryString: function () {
var params = {
'param1': $.trim($('#param1').val()),
'param2': $.trim($('#param2').val())
}
for (p in params) {
if (params.p == null || params.p == '') {
delete params.p;
}
}
return params;
}
Don't set it if it's empty is all:
var keyword = $.trim($('#keyword').val());
var params = {};
if(keyword) {
params.keyword = keyword;
}
return params;
(edit)
If you have lots of things to check, consider using either a loop:
var items = {
keyword: $.trim($('#keyword').val())
// etc.
};
var params = {};
for(var x in items) {
if(items.hasOwnProperty(x) && items[x]) {
params[x] = items[x];
}
}
return params;
or a function of some kind, for example:
var params = {};
function check(name) {
var value = $.trim($('#' + name).val());
if(value) {
params[name] = value;
}
}
check('keyword');
// etc.
return params;
As an empty string is a falsy value in JavaScript you can simpley check if val() is true:
setQueryString: function () {
var keyword = $('#keyword').val();
if(keyword){
var params = {
"keyword": $.trim(keyword)
};
return params;
}
}
Try something like:
setQueryString: function () {
var keyword = $.trim($('#keyword').val());
var params = {};
if(keyword !== undefined && keyword !== '') {
params.keyword = keyword;
}
return params;
}
I believe you need extend: http://api.jquery.com/jQuery.extend/

Categories