I have an object containing an array:
<script type="text/javascript">
var statusData = {
Status: []
};
var uniqueCounter = 1
function createJsonFmtData() {
// Used as unique id at client side
var uniqueCounter =uniqueCounter + 1;
statusData.Status.push({
"Name": Name,
"Time": Time,
"Email": Mail,
"Name": Type,
"Value": Value,
"uniqueId": uniqueCounter
});
}
function DelNewlyCreStatusRow(rowId) {
// First pop elment from json data
var val;
for (val = 0; val < statusData.Status.length; ++val) {
if (statusData.Status[val].uniqueId == rowId) {
delete statusData.Status[val];
break;
}
}
</script>
When try to call DelNewlyCreStatusRow it gives the error:
TypeError: statusData.Status[val] is undefined
I am not able to figure it out here where as I have declared it as global.
This is because you are trying to delete from the array incorrectly. delete operator is quite funny on arrays. It replaces element with undefined. Check this out:
>>> var A = [1, 2, 3];
>>> delete a[1];
>>> A;
[1, undefined, 3];
Thus calling DelNewlyCreStatusRow multiple times will throw an exception, because statusData.Status[val].uniqueId cannot be evaluated ( statusData.Status[val] is undefined ).
To fix this use this code instead of delete:
var val;
for (val = 0; val < statusData.Status.length; ++val) {
if (statusData.Status[val].uniqueId == rowId) {
statusData.Status.splice( val, 1 );
break;
}
}
Note that splice modifies an array, so if you want to do multiple deletes in one go, then you will have to replace for loop with while ( and refactor the code a bit ). This is not needed here because of break statement.
You should replace
delete statusData.Status[val];
with
statusData.Status.splice(val,1);
val -= 1;
to remove an object in an array.
The function DelNewlyCreStatusRow missing a closing '}'
function DelNewlyCreStatusRow(rowId) {
// First pop elment from json data
var val;
for (val = 0; val < statusData.Status.length; ++val) {
if (statusData.Status[val].uniqueId == rowId) {
delete statusData.Status[val];
break;
}
}
}
You made an Error in your Code at the second var declaration inside the Function.
var uniqueCounter = uniqueCounter + 1 => NAN + 1.
You dont need the var a Second time so it's just
uniqueCounter = uniqueCounter + 1 => 2.
Then delete works fine in my Case.
<script type="text/javascript">
var statusData = {
Status : []
};
var uniqueCounter = 1
function createJsonFmtData() {
var statusName = $('#<%= ddlStatus.ClientID %> option:selected').text();
var dateTime = $("#body_ctl04_ctl02").val();
var forceMail = ($("#chkForceMail").is(':checked')) ? 1 : 0;
var noteType = $('#divTrackId').text();
var dataValue = $("#<%=txtTrackId.ClientID %>").val();
var curLogedUserName = $("#<%=curLoginUserName.ClientID %>").val();
// Used as unique id at client side
uniqueCounter = uniqueCounter + 1;
statusData.Status.push({
"statusName" : statusName,
"dateTime" : dateTime,
"forceEmail" : forceMail,
"typeName" : noteType,
"dataValue" : dataValue,
"uniqueId" : uniqueCounter
});
}
function DelNewlyCreStatusRow(rowId) {
// First pop elment from json data
var val;
for ( val = 0; val < statusData.Status.length; ++val) {
if (statusData.Status[val].uniqueId == rowId) {
console.log(typeof(statusData.Status[val]));
delete statusData.Status[val];
break;
}
}
}
createJsonFmtData();
console.log(statusData);
DelNewlyCreStatusRow(2);
console.log(statusData);
</script>
Related
I have this object:
var registered_screens = {
handle_1 : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3'
};
And here's what I tried to get its neighbors:
function get_neighbors( current_step ) {
var steps = {
next: '',
previous: ''
};
for( var i in registered_screens ) {
if( current_step == registered_screens[i] ) {
if(registered_screens.hasOwnProperty(registered_screens[i])) {
steps.next = registered_screens[i+1];
}
if(registered_screens.hasOwnProperty(registered_screens[i-1])) {
steps.previous = registered_screens[i-1];
}
}
}
return steps;
}
Obviously, this is a no-go because an object can't be parsed the same as an array, but just wanted to show what I tried.
What I'd want to get is, if I call get_neighbors('handle_2'), return:
steps { prev : 'handle_1' , next : 'handle_3' }
Or, for get_neighbors('handle_3'):
steps { prev : 'handle_2', next : null }
I've also attempted:
var registered_screens = {
handle_one : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3'
};
var key_values = Object.keys(registered_screens);
for( var i = 0; i < key_values.length; i++ ) {
console.log(registered_screens.key_values[i]);
}
But this throws:
main.js?ver=4.9.6:18 Uncaught TypeError: Cannot read property '0' of undefined
main.js?ver=4.9.6:18
main.js?ver=4.9.6:270
Funnily enough, I checked what the values for key_values[i] are and they're the right handles.
It seems JS has a hard time building variables out of strings?
I don't like it much and would look at a restructure to make registered_screens an array. I also would not trust this code due to object order can not be guaranteed.
That said, this will work with my browser.
Edit: Added an array version, which I would trust but would expand for blank (undefined) results.
// array version
var aScreens = [];
aScreens['handle_one'] = 'step_1';
aScreens['handle_2'] = 'step_2';
aScreens['handle_3'] = 'step_3';
function getArrayPrevNext(a,current) {
var x,p = '',n = '',found = false;
for(x in a) {
if (found) {
n = x;
break;
} else if (x == current) {
found = true;
} else {
p = x;
}
}
return {prev:p,next:n};
}
var aSteps = getArrayPrevNext(aScreens,'handle_3');
console.log('array prev['+ aSteps.prev +'], next['+ aSteps.next +']');
var p = aSteps.prev, n = aSteps.next;
console.log('handle prev['+ aScreens[p] +'], next['+ aScreens[n] +']');
console.log('handle alt prev['+ aScreens[aSteps.prev] +'], next['+ aScreens[aSteps.next] +']');
// Object version
var registered_screens = {
handle_one : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3'
};
function getPreviousNext(obj,current) {
var prev = '', nxt = '', found = false;
Object.keys(obj).forEach(function(key) {
if (! nxt) {
if (found) {
nxt = key;
} else if (key == current) {
found = true;
} else {
prev = key;
}
}
});
return {prev:prev,next:nxt};
}
var steps = getPreviousNext(registered_screens,'handle_3');
console.log('Object steps:['+ steps.prev +']['+ steps.next +']');
Your second attempt is what I thought as well, it should work fine if you correct the key access like below
var registered_screens = {
handle_one : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3'
};
var key_values = Object.keys(registered_screens);
for( var i = 0; i < key_values.length; i++ ) {
console.log(registered_screens[key_values[i]]);
}
As far as I know, the keys in the object are un-ordered and we should not rely on that order, like others have mentioned, it's order will not be the same as when you created, but your requirement seems like it can make use of Object.keys to iterate and find next and prev keys to some extent
To your question, why this registered_screens[key_values[i]] works and not registered_screens.key_values[i], the dot notation will not work for dynamic keys, i.e key_values[i] is not a key, it's a variable holding the key, in such cases you have to access it like an array like Object[keyNameHolder]
This script does a very basic parsing of object keys - it assumes it is always in the format of handle_{n} - based on that it creates an array that holds the keys in proper order, which then is searched for and uses n-1 and n+1 to return prev and next (if possible, else null). And yes i know, most browsers would sort it correctly nonetheless so that in most scenarios you would get the proper order (included a console output for comparison)
var screens = {
handle_1 : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3',
handle_4 : 'step_4',
handle_5 : 'step_5',
handle_6 : 'step_6',
handle_7 : 'step_7',
handle_8 : 'step_8',
handle_9 : 'step_9',
handle_10 : 'step_10',
handle_11 : 'step_11',
},
keyParser = (key) => parseInt(key.replace('handle_', '')),
keySorter = (a, b) => keyParser(a) - keyParser(b),
handleKeys = Object.keys(screens).sort(keySorter);
// Compare key ordering in your browser
// It will be most likely identic, since most modern browsers understand that
// it should sort by {str}_{int} and not by {str}_{str} if an {int} is present
// but chances are that for instance IE9 would do the latter, so it could be that
// with browser ordering handle_10 and handle_11 come after handle_1
console.log('browser ordering:', Object.keys(screens));
console.log('parsed ordering:', handleKeys);
function getSteps(handle) {
var pos = handleKeys.indexOf(handle);
if(pos === -1) throw(`Can't find handle ${handle} in screens`);
return {
current: screens[handleKeys[pos]],
prev: pos > 0 ? screens[handleKeys[pos-1]] : null,
next: pos < handleKeys.length-1 ? screens[handleKeys[pos+1]] : null
}
}
console.log(
getSteps('handle_1'),
getSteps('handle_2'),
getSteps('handle_6'),
getSteps('handle_10'),
getSteps('handle_11')
);
Also a good read: https://hackernoon.com/out-of-order-keys-in-es6-objects-d5cede7dc92e
As far as I know the answer is there is no direct way, but you can play around this in many ways.
One idea is that you can play with the naming convention of your data, for example,
call the object items as handle_1 instead of "handle_one" and so on, that
way you can loop around the array using index ['handle_' + i] but notice that you can't do ['handle_' + i + 1] or else you will have a wrong index value because the string conversion will happen before the summation.
I hope this helps.
I made this work:
var registered_screens = {
handle_1 : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3'
};
function get_neighbors( current_step ) {
var steps = {
next: '',
previous: ''
};
var key_values = Object.keys(registered_screens);
for( var i = 0; i < key_values.length; i++ ) {
if( current_step == registered_screens[key_values[i]]) {
if( !(registered_screens[key_values[i-1]] == null) ) {
steps.previous = registered_screens[key_values[i-1]];
}
if( !(registered_screens[key_values[i+1]] == null) ) {
steps.next = registered_screens[key_values[i+1]];
}
}
}
return steps;
}
And so, get_neighbors('step_2') reliably (in my tests) returns:
steps : { next : 'step_3', previous: 'step_1' };
I have this code below to search for a string of search string_search_* matched.
I'm wondering if there's any easier way to do this like maybe add multiple search term in indexof? is that possible?
My goal: just add variable string:
string_search4, 5, 6 and so on..
string = "this is a .bigcommerce.com site";
var string_search1 = 'cdn.shopify.com/s';
var string_search2 = '.bigcommerce.com/';
var string_search3 = 'woocommerce/';
// start checkig with SHOPIFY first
var s = string.indexOf(string_search1 );
var found_s = String(s);
// IF FOUND - look for the full url hubspot - like the mp4 url
if (found_s != '-1') {
var result = 'SHOPIFY'
return result;
}
// if NOT FOUND, check with BIGCOMMERCE
else {
var b = html.indexOf(string_search2);
var found_b = String(b);
if (found_b != '-1') {
var result = 'BIGCOMMERCE'
return result;
}
else {
var w = html.indexOf(string_search3);
var found_w = String(w);
if (found_w != '-1') {
var result = 'WOO COMMERCE'
return result;
}
else {
var result = 'CANNOT INDENTIFY CMS'
return result
}
}
}
This may look a little long, but is very expandable.
// Our "key" object and defaults
var sObj = function(id){
this.id = id;
this.found = false;
};
// Our self-contained object with search and result
// functions. This is were and how we can expand quickly
var s = {
'ob': [],
'find': function(haystack) {
if (this.ob) {
for(var x in this.ob) {
this.ob[x].found = (haystack.indexOf(this.ob[x].id) > -1);
}
}
},
'result': function() {
var r = "";
if (this.ob) {
for(var x in this.ob) {
if (this.ob[x].found) {
r += ","+this.ob[x].id;
}
}
}
return (r == "") ? r : r.substr(1);
}
};
// Create the object array with the "id"
// Add as many as you want.
s.ob.push(new sObj('shopify.com'));
s.ob.push(new sObj('bigcommerce.com'));
s.ob.push(new sObj('woocommerce.com'));
// quick debug for testing
//for(var x in s.ob) {
// console.log('x:['+ x +']['+ s.ob[x].id +']['+ s.ob[x].found +']');
//}
// Our string to be tested
var data = "this is a .bigcommerce.com site";
// check if the data matches one of the sObj ids
s.find(data);
// get the results
console.log('result:['+ s.result() +']');
// And for a second test (2 results)
data = "can you shopify.com or woocommerce.com me?";
s.find(data);
console.log('result:['+ s.result() +']');
I am working on displaying the Json output of a generated flowchart. I have stored the dropped elements' details in an array called finalArray and am simply adding it to the Json display. All the details seem to be properly displayed except for the attribute names and their attribute types that are retrieved from another array.
I've commented the part that doesn't work in the following code segment
Code in Context
function saveFlowchart(){
var nodes = [];
var matches = [];
var searchEles = document.getElementById("container").children;
for(var i = 0; i < searchEles.length; i++)
{
matches.push(searchEles[i]);
var idOfEl = searchEles[i].id;
if(searchEles[i].id !=null || searchEles[i].id !="")
{
var $element = $("#" + searchEles[i].id);
var dropElem = $("#" + searchEles[i].id).attr('class');
var position = $element.position();
position.bottom = position.top + $element.height();
position.right = position.left + $element.width();
//alert("class:"+dropElem+"\nTop position: " + position.top + "\nLeft position: " + position.left + "\nBottom position: " + position.bottom + "\nRight position: " + position.right);
finalArray[i] = [];
finalArray[idOfEl-1][0]= idOfEl;
finalArray[idOfEl-1][1]= dropElem;
finalArray[idOfEl-1][2]= [];
finalArray[idOfEl-1][2][0] = position.top;
finalArray[idOfEl-1][2][1] = position.left;
finalArray[idOfEl-1][2][2] = position.bottom;
finalArray[idOfEl-1][2][3] = position.right;
var elId = parseInt(idOfEl);
if (dropElem=="streamdrop ui-draggable")
{
for(var count=0;count<100;count++)
{
if(createdImportStreamArray[count][0]==idOfEl)
{
finalArray[elId-1][3]= createdImportStreamArray[count][1]; //Selected Stream from Predefined Streams
finalArray[elId-1][4]= createdImportStreamArray[count][2]; //asName
//alert("createdImportStreamArray[count][0]==elId\n"+count);
}
else if(createdExportStreamArray[count][0]==idOfEl)
{
finalArray[elId-1][3]= createdExportStreamArray[count][1]; //Selected Stream from Predefined Streams
finalArray[elId-1][4]= createdExportStreamArray[count][2]; //asName
}
else if(createdDefinedStreamArray[count][0]==idOfEl)
{
finalArray[elId-1][3]= createdDefinedStreamArray[count][1]; //Stream Name
finalArray[elId-1][4]= createdDefinedStreamArray[count][4]; //Number of Attributes
finalArray[elId-1][5]=[];
for(var f=0;f<createdDefinedStreamArray[count][4].length;f++)
{
finalArray[elId-1][5][f]=[];
The following two are not displayed individually. Instead only "[]" is shown
finalArray[elId-1][5][f][0]=createdDefinedStreamArray[count][2][f][0]; //Attribute Name
finalArray[elId-1][5][f][1]=createdDefinedStreamArray[count][2][f][1]; // Attribute Type
}
}
}
}
else if (dropElem=="wstream ui-draggable")
{
finalArray[elId-1][3]= createdWindowStreamArray[elId-1][1]; // Window Name
finalArray[elId-1][4]= createdImportStreamArray[elId-1][2]; //Selected Stream Index
finalArray[elId-1][4]= createdImportStreamArray[elId-1][3]; //Selected Stream
finalArray[elId-1][5]= [];
var AttributeNumber = createdWindowStreamArray[elId-1][4].length;
for(var attrFill=0;attrFill<AttributeNumber;attrFill++)
{
finalArray[elId-1][5][attrFill]=[];
finalArray[elId-1][5][attrFill][0]=createdWindowStreamArray[elId-1][4][attrFill][0];
finalArray[elId-1][5][attrFill][1]=createdWindowStreamArray[elId-1][4][attrFill][1];
}
//alert("createdImportStreamArray[count][0]==elId\n"+count);
}
else if (dropElem=="squery ui-draggable")
{
ElementType="squery";
}
else if (dropElem=="wquery ui-draggable")
{
ElementType="wquery";
}
else if (dropElem=="joquery ui-draggable")
{
ElementType="joquery";
}
else if(dropElem=="stquery ui-draggable")
{
ElementType="stquery";
}
else if(dropElem=="partitiondrop ui-draggable")
{
ElementType="partitiondrop";
}
}
}
alert(finalArray);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
$(".node").each(function (idx, elem) {
var $elem = $(elem);
var endpoints = jsPlumb.getEndpoints($elem.attr('id'));
console.log('endpoints of '+$elem.attr('id'));
console.log(endpoints);
nodes.push({
blockId: $elem.attr('id'),
nodetype: $elem.attr('data-nodetype'),
positionX: parseInt($elem.css("left"), 10),
positionY: parseInt($elem.css("top"), 10)
});
});
var connections = [];
$.each(jsPlumb.getConnections(), function (idx, connection) {
connections.push({
connectionId: connection.id,
pageSourceId: connection.sourceId,
pageTargetId: connection.targetId
});
});
var flowChart = {};
flowChart.nodes = nodes;
flowChart.connections = connections;
flowChart.elements =finalArray;
flowChart.numberOfElements = finalArray.length;
var flowChartJson = JSON.stringify(flowChart);
//console.log(flowChartJson);
$('#jsonOutput').val(flowChartJson);
}
Current Json Output
Basic Interface
createdDefinedStream Array
//Array that stores all Defined stream data
var createdDefinedStreamArray = [];
for(var x = 0; x < 100; x++){
createdDefinedStreamArray[x] = [];
for(var y = 0; y < 5; y++){
createdDefinedStreamArray[x][y] = null
}
}
function storeDefinedStreamInfo(newAgent,i,e,kind)
{
var StrName= document.getElementById("StreamNameInput").value;
var StreamElementID = i;
var table = document.getElementById('attrtable');
var tblerows = (table.rows.length);
createdDefinedStreamArray[i][2]=new Array(tblerows);
for (r = 1; r < tblerows; r++) {
for(var c=0; c<1;c++) {
var attrNm = table.rows[r].cells[c].innerHTML;
var attrTp = table.rows[r].cells[1].innerHTML;
createdDefinedStreamArray[i][2][r-1]= new Array(2);
createdDefinedStreamArray[i][2][r-1][0]=attrNm;
createdDefinedStreamArray[i][2][r-1][1]=attrTp;
}
}
createdDefinedStreamArray[i][0]=StreamElementID;
createdDefinedStreamArray[i][1]=StrName;
createdDefinedStreamArray[i][3]="Defined Stream";
createdDefinedStreamArray[i][4]= tblerows;
var prop = $('<a onclick="doclickDefine(this)"><b><img src="../Images/settings.png" class="settingsIconLoc"></b></a> ').attr('id', (i+'-prop'));
var conIcon = $('<img src="../Images/connection.png" onclick="connectionShowHideToggle(this)" class="showIconDefined"></b></a> ').attr('id', (i+'vis'));
newAgent.text(StrName).append('<a class="boxclose" id="boxclose"><b><img src="../Images/Cancel.png"></b></a> ').append(conIcon).append(prop);
dropCompleteElement(newAgent,i,e,kind);
}
Could you please try running this code on your data to see if I missed anything and if the problem is solved? I replaced all of the loops with maps, so it's a little bit clearer which data gets selected where.
function saveFlowchart(){
var nodes = [],
searchElements = Array.prototype.slice.call(document.querySelector('#container').childNodes),
matches = searchElements.slice(),
finalArray,
ElementType, // this was global in the example and is currently not used in the sample code.
map = function map( ary, field ) {
return ary.reduce(function( map, element ) {
map[element[field]] = element;
return map;
}, {});
},
// Let's create a bunch of maps so we can reference each id directly instead of having to loop Each array for each element several times.
// This results in easier to understand code and runs faster, since nested arrays several levels deep can cause confusion.
// Noted the signature of each provided array.
// importStreamMap: [ id, selected stream, asName ]
importStreamMap = map(createdImportStreamArray, 0),
// exportStreamMap: [ id, selected stream, asName ]
exportStreamMap = map(createdExportStreamArray, 0),
// definedStreamMap: [ id, stream name, [ [attr1 name, attr1 type], [attr2 name, attr2 type], ... ], ???, attr count ]
definedStreamMap = map(createdDefinedStreamArray, 0),
// windowStreamMap: [ id, window name, selected stream index, selected stream (name?) ]
windowStreamMap = map(createdWindowStreamArray, 0),
classHandlers = {
'streamdrop ui-draggable' : function( id, result ) {
if (importStreamMap.hasOwnProperty(id)) {
result.push(importStreamMap[id][1]); // selected stream
result.push(importStreamMap[id][2]); // asName
}
else if (exportStreamMap.hasOwnProperty(id)) {
result.push(exportStreamMap[id][1]); // selected stream
result.push(exportStreamMap[id][2]); // asName
}
else if (definedStreamMap.hasOwnProperty(id)) {
result.push(definedStreamMap[id][1]); // stream name
result.push(definedStreamMap[id][4]); // attr count
result.push(definedStreamMap[id][2].slice()); // just clone the entire array of key/value pairs, no need to recreate it since they are strings.
}
},
'wstream ui-draggable' : function( id, result ) {
result.push(windowStreamMap[id][1]); // window name
// one of these two is obsolete, since the second overwrites the first. Selected stream according to the array signature ????
// result.push(importStreamMap[id][2]);
result.push(importStreamMap[id][3]);
result.push(windowStreamMap[id][4].slice()); // clone the array again.
},
'wquery ui-draggable' : function( id, result ) {
ElementType = 'wquery';
},
'joquery ui-draggable' : function( id, result ) {
ElementType = 'joquery';
},
'stquery ui-draggable' : function( id, result ) {
ElementType = 'stquery';
},
'partitiondrop ui-draggable' : function( id, result ) {
ElementType = 'partitiondrop';
}
};
finalArray = searchElements.reduce(function( ary, element ) {
var id = parseInt(element.id, 10),
$element,
dropCls,
position,
result;
if (id) {
$element = element.querySelector('#' + id);
dropCls = $element.className;
position = $element.position();
position.bottom = position.top + $element.height();
position.right = position.left + $element.width();
result = [ id, dropCls, [ position.top, position.left, position.bottom, position.right ] ];
classHandlers[dropCls](id, result);
ary.push(result);
}
return ary;
}, []);
////////////////////////////////////////////////////////////////////
// Rest of the code stays the same. If the attributes aren't showing up yet, check if the array is correct and if the indexes are ok.
// From the array signatures, we get that the createdDefinedStreamArray contains the attributes instead of the createdWindowStreamArray.
// For the record, it'd be easier to just use key-value pairs and objects in the JSON, if the API allows that.
}
I would like to make multiple calls to get JSONPs and insert their values into an array inside of a for loop. However, currently my result is an array filled with undefined values. How can I make this work properly?
Code:
function fetchColumnRange(sheetId,colStart,colEnd,row) {
var colStartNum = isNumber(colStart) ? colStart : excelColumnNumber(colStart);
var colEndNum = isNumber(colEnd) ? colEnd : excelColumnNumber(colEnd);
var values = [], value;
for (i = colStartNum; i <= colEndNum; i++) {
value = fetchCellValue(sheetId,i,row); // IT HAS TO WAIT, BUT HOW???
values.push(value);
}
return values;
}
function fetchCellValue(sheetId,col,row) {
var script = document.createElement('script');
var colNum = isNumber(col) ? col : excelColumnNumber(col); // Column input can be either a number or a letter
script.src = 'https://spreadsheets.google.com/feeds/cells/0AtMEoZDi5-pedElCS1lrVnp0Yk1vbFdPaUlOc3F3a2c/' + sheetId + '/public/values/R' + row + 'C' + colNum + '?alt=json-in-script&callback=insertCellValue';
document.body.appendChild(script);
}
function insertCellValue(data) {
var value = data.entry['gs$cell']['$t'];
return value;
}
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
console.log(fetchCellValue(1,'A',2));
console.log(fetchCellValue(1,'B',2));
console.log(fetchColumnRange(1,'A','B',2));
Output:
["Test 1"]
["Lorem ipsum"]
[undefined, undefined]
I have a json.json file like this
{
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
}
And this script im using to read the file
<script type='text/javascript'>
$(window).load(function(){
$.getJSON("json.json", function(person){
document.write(person.name3);
});
});
</script>
This script is made to point out all of the data from "name3" but i need only "dr3" value from "name3" to be stored to be written.
How to do that?
You can store it like this using combination of split() calls.
var dr3val = person.name3.split("&")[2].split("=")[1];
console.log(dr3val); // "Sting3"
The above will work if the order is same. Else you can use the below
var dr3val = person.name3.replace(/.*?dr3=(.+)?&.*/,"$1");
console.log(dr3val); // "Sting3"
You should change your json to this:
{
"name1":
{
"ts1" : "Hallo",
"ts2" : "Hillarry",
"ts3" : "Sting",
"ts4" : "Storm"
}
}
this way it makes your jsonstring much easier to use.
Get the data from it like this:
person.name1.ts1
var json = {
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
};
var name3 = json.name3.split('&');
for (var i = 0; i < name3.length; i++) {
if (name3[i].indexOf("dr3=") > -1) {
var value = name3[i].replace("dr3=", "");
alert(value);
}
}
Implement this jQuery plugin i made for a similar case i had to solve some time ago. This plugin has the benefit that it handles multiple occurring variables and gathers them within an array, simulating a webserver behaviour.
<script type='text/javascript'>
(function($) {
$.StringParams = function(string) {
if (string == "") return {};
var result = {},
matches = string.split('&');
for(var i = 0, pair, key, value; i < matches.length; i++) {
pair = matches[i].split('=');
key = pair[0];
if(pair.length == 2) {
value = decodeURIComponent(pair[1].replace(/\+/g, " "));
} else {
value = null;
}
switch($.type(result[key])) {
case 'undefined':
result[key] = value;
break;
case 'array':
result[key].push(value);
break;
default:
result[key] = [result[key], value];
}
}
return result;
}
})(jQuery);
</script>
Then in your code do:
<script type='text/javascript'>
$(window).load(function(){
var attributes3;
$.getJSON("json.json", function(person){
attributes3 = $.StringParams(person.name3)
console.log(attributes3.dr3);
});
});
</script>
Underscore solution:
_.map(json, function(query) { //map the value of each property in json object
return _.object( //to an object created from array
query.split('&') //resulting from splitting the query at &
.map(function(keyval) { //and turning each of the key=value parts
return keyval.split('='); //into a 2-element array split at the equals.
);
})
The result of the query.split... part is
[ [ 'ts1', 'Hallo'], ['ts2', 'Hillarry'], ... ]
Underscore's _.object function turns that into
{ ts1: 'Hallo', ts2: 'Hillarry', ... }
The end result is
{
name1: { ts1: 'hHallo', ts2: 'Hillarry, ...},
name2: { ...
}
Now result can be obtained with object.name3.dr3.
Avoiding Underscore
However, if you hate Underscore or don't want to use it, what it's doing with _.map and _.object is not hard to replicate, and could be a useful learning exercise. Both use the useful Array#reduce function.
function object_map(object, fn) {
return Object.keys(object).reduce(function(result, key) {
result[key] = fn(object[key]);
return result;
}, {});
}
function object_from_keyvals(keyvals) {
return keyvals.reduce(function(result, v) {
result[v[0]] = v[1];
return result;
}, {});
}
:
var person={
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
}
var pN = person.name3;
var toSearch = 'dr3';
var ar = pN.split('&');
var result = '';
for(var i=0; i< ar.length; i++)
if(ar[i].indexOf(toSearch) >= 0 )
result=ar[i].split('=')[1];
console.log('result=='+result);