Cannot copy object property in javascript - javascript

I have an ajax call which gathers the parent and child dependencies for some entities. Inside the success function I assign what ajax returns (data) to a global level object.
$.ajax(
{
type: "POST",
url: 'ajax_handler.php',
data: {action:'get_dependencies', relation:relation, 'jobs[]':jobs, project:project},
dataType: 'json',
async: false, //do not change
success: function(data)
{
for(var key in data)
{
if( data.hasOwnProperty(key) )
{
//Copy data object to document level existingDependency object
existingDependency[key] = data[key];
}
}
},
error: function(xhr)
{
alert('error2:'+xhr.responseText);
}
});
I call this AJAX which is in a function twice. One for parents and one for children. I figured that this line existingDependency[key] = data[key]; is reassigning the object thus the previous assignment is lost. In other words the existingDependency object cannot hold both ['parent'] and ['child'] properties together.
To fix this I did the below changes so that existingDependency holds both properties:
success: function(data)
{
for(var key in data)
{
if( data[key].hasOwnProperty(relation) )
{
//Copy data object to document level existingDependency object
existingDependency[key][relation] = data[key][relation];
}
}
}
But this does not work at all. existingDependency object is empty. Below alerts empty.
var keys = '';
for(key in existingDependency)
{
keys += key+'\n';
}
alert(keys);
Any ideas why this assignment existingDependency[key][relation] = data[key][relation] does not work? data[key][relation] holds an array if it makes any difference.

Use extend:
$.ajax({
type: "POST",
url: 'ajax_handler.php',
data: {
action:'get_dependencies',
relation:relation,
'jobs[]':jobs,
project:project
},
dataType: 'json',
async: false, //do not change
success: function(data) {
$.extend(true, existingDependency, data);//this will copy/merge "data" into "existingDependency". properties from "data" that also exist in "existingDependency" will be overwritten with those from "data".
},
error: function(xhr) {
alert('error2:'+xhr.responseText);
}
});
As for why eD[key] = data[key] works while eD[key][relation] = data[key][relation] does not its hard to say without being able to run your code and debug it. But if eD[key] did not yet exist yet then it would not be able to add "relation" to it. A possible fix for that would have been:
if (!eD.hasOwnProperty(key)){
eD[key] = {};
}
eD[key][relation] = data[key][relation];

Related

Use form naming to reach json data in Javascript/jQuery?

I have the following input name: dynamic[elements][1][slider][image1]
When performing an ajax call, a json response with settings and its value is returned.
$.ajax({
url: '/get/settings',
type: 'POST',
data: formData,
async: false,
success: function (data) {
});
How can i get the value of dynamic[elements][1][slider][image1] the easiest way? It works to get the value like this:
data.dynamic.elements[1].slider.image1
So:
$.ajax({
url: '/get/settings',
type: 'POST',
data: formData,
async: false,
success: function (data) {
console.log(data.dynamic.elements[1].slider.image1);
});
But isn't their any better way of getting the value? The only identifier I have to get the value, is the name of the input field which is dynamic[elements][1][slider][image1]. So i would need to extract this string and put it together as data.dynamic.elements[1].slider.image1 to then make it a dynamic variable somehow (to finally get the value)?
Example ajax response:
{
"success": 1,
"dynamic": {
"elements": [
{
"title": {
"title": "Our beautiful topic"
}
},
{
"slider": {
"image1": "5zw3ucypzp3qham.png",
"image1_link": "hellor"
}
}
]
}
}
You may choose to write a generic function for the purpose of retrieving data from object. The function should look something like below. Though the function may not be foolproof but should be enough for proof-of-concept.
function getObjectData(target, path) {
// if the path is not in dot notation first convert
if (path.indexOf(".") == -1)
path = path.replace(/\[/g, ".").replace(/\]/g, "");
var parts = path.split(".");
return parts.reduce(function (acc, currentVal) {
return acc ? (acc[currentVal] || undefined) : acc;
}, target);
}
//usage
getObjectData(data, "dynamic.elements.0.slider.image1"); //undefined
getObjectData(data, "dynamic.elements.1.slider.image1"); //5zw3ucypzp3qham.png
getObjectData(data, "dynamic[elements][1][slider][image1]"); //5zw3ucypzp3qham.png
Hope this helps.

Accessing an object property without knowing it's parent with a for in loop

I am trying to access a value retrieved from an external API. Specifically, it's a shortened URL. The shortener takes the long URL saves it as an object itself within an object and places the shortened URL within this object (see screenshot).
I won't know the exact value of the long URL so I am trying to use a for in loop to access the shortUrl (since I know that is always the name if it's key) and for now print it to the console.
I get variations of undefined, [object, object] or null.
What is missing here?
longUrl = "longUrl=" + longUrl;
$.ajax({
type: 'get',
dataType: 'jsonp',
url:'http://api.shortswitch.com/shorten?apiKey=3f5f69733156cce575b9a7ab1783ff4f4f0a8b5c&format=json&',
crossDomain: true,
data: longUrl,
success: function(data){
for (var shortUrl in data){
if(data.hasOwnProperty(shortUrl)) {
console.log(data[shortUrl]);
}
}
}
});
Please try use data.results instead of data:
var shortURLs = [];
for(var key in data.results) {
shortURLs.push(data.results[key].shortUrl);
}
console.log(shortURLs);
Demo:
var longUrl = {longUrl: "http://stackoverflow.com/questions/38417777/accessing-an-object-property-without-knowing-its-parent-with-a-for-in-loop/38417810#38417810"};
$.ajax({
type: 'GET',
dataType: 'jsonp',
url:'http://api.shortswitch.com/shorten?apiKey=3f5f69733156cce575b9a7ab1783ff4f4f0a8b5c&format=json&',
crossDomain: true,
data: longUrl,
success: function(data){
var shortURLs = [];
for(var key in data.results) {
shortURLs.push(data.results[key].shortUrl);
}
console.log(shortURLs);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You appear to be on the right track with iterating through the object's property and accessing that key. Based on your example data, you should be checking data.result not data.
Here's an example plunkr: https://plnkr.co/edit/7De7ZVPHz7x2n1OcKXmi?p=info
Here's the relevant code:
var data = {
errorMessage: "",
statusCode: "OK",
errorCode: "0",
results: {
"http://hello?cmp=EXP:da:paid::320x50": {
hash: "B3uXHF",
shortUrl: "http://at.law.com/B3uXHf",
longUrl: "http://hello?cmp=EXP:da:paid::320x50"
}
}
};
function getShortURL(data) {
for (var property in data.results) {
if (data.results.hasOwnProperty(property)) {
return data.results[property].shortUrl;
}
}
}
console.log(getShortURL(data));
Since you do not know the longUrl, you just need to access that object's child properties to access the shortUrl key. You really are just iterating through the indexes of the object.

Declare one Ajax Function and fill it with different variables

I'm trying to make my page more efficient by using a separated ".js" file and trying to declare multilple used functions only one time. So I have to declare them in a way, that they caa be used for different situations. For Example passing different data.
Here is my Ajax Function in the "functions.js" file:
function CallAjax(type, url, data, div){
$.ajax({
type: type,
url: url,
data: data,
success: function (data) {
console.log(data);
$(div).html(data);
}
});
}
Here is my Code in my PHP File where I use this function and pass Parameters:
CallAjax('POST', 'about.php', '{ aufid : id }', '#con2');
My Problem is the "data" section. How can I declare it? The way I'm doing it doesn't work.
I don't want to use a new Ajax Function everytime when I need different data... I'm trying to trigger less functions as possible.
If you have any tips to make the page more efficient by trying to use less code, then it would be awesome if you mention them, too! Thank you!
you can do it like this:
var obj = {
aufid: 1
};
CallAjax('POST', 'about.php', obj, '#con2');
I propose js callback:
function CallAjax(type, url, data, div){
$.ajax({
type: type,
url: url,
data: data,
success: function (data) {
callback(data);
}
});
}
var obj = {
id:1
};
CallAjax('POST', 'about.php', obj, function(response){
$(div).html(response); //or other
});
or a more elegant way in promise:
function CallAjax(type, url, data){
return $.ajax({
type: type,
url: url,
data: data,
});
}
var obj = { id: 1 };
var jxhr = CallAjax('POST', 'about.php', obj);
jxhr.done(function(response){
//successful callback goes here...
}).fail(function(response){
//failure callback goes here...
}).always(function(response){
//always callback goes here...
});
: )

Backbone.js Unable to parse response from collectio.toJSON()

I am learning Backbone and it would be great if someone can help me with this issue. After I do a fetch on my collection, in success callback I get the parsed data using collection.toJSON(), this actually returns an object and I am unable to get anything out of this object. This object actually has data that I need.
My question is how do I access rows property in my object. Here is my code for your reference
var testCollection = Backbone.Collection.extend({
model:myModel,
url: '/myApiEndPoint',
data: '',
initialize: function(models, options) {
this.data = models.data;
},
fetch: function(options) {
var ajaxConfig = {
url: this.url,
data: this.data,
type: 'POST',
dataType: 'text',
contentType: 'text/xml',
parse: true
};
options = _.extend({}, ajaxConfig, options);
return Backbone.Collection.prototype.fetch.call(this, options);
},
parse: function(xmlResponse) {
// I have some parsing logic to extract uid and rows from my xmlResponse
return {
uid: uid,
rows: rows
};
},
});
var collObj = new testCollection({data: xmlQuery1});
collObj.fetch({
success: function(collection){
// This code block will be triggered only after receiving the data.
console.log(collection.toJSON());
}
});
As the name toJSON suggests, it returns you the array of JSON objects where each object is a Model's JSON object. You can fetch the required properties in this way:
collObj.fetch({
success: function(collection){
// This code block will be triggered only after receiving the data.
console.log(collection.toJSON());
var uid = 'uid-of-an-object-to-access';
var rows = collection.get(uid).get('rows');
console.log(rows);
}
});

Knockout mapping data from ajax post vs Static data

I've encounted a strange problem with Ko mapping.
I use this piece of code:
var PList = [{ "Region": { "RegionName": "SomeRegion" }, "CDetails": {}, "Category": { "Name": "SomeCategory" }, "PSource": 1, "PDate": "0001-01-01T00:00:00"}];
var PViewModel = ko.mapping.fromJS(search('someSearch', 'True'));
var PViewModel2 = ko.mapping.fromJS(PostList);
function search(queryString, isFirst) {
$.ajax({
type: 'POST',
url: 'url',
data: { 'searchQuery': queryString },
dataType: 'json',
success: function (dt) {
if (isFirst != 'True') {
ko.mapping.fromJS(dt, PostsViewModel);
}
return dt;
}
});
};
Strangely I see 2 outcomes:
When I go to PViewModel (the one populated by ajax) I see it as undefined
When I go to PViewModel2 (the one with static data) I can see the objects as expected
*The static data of PViewModel2 is just a copy of the data returned by the ajax post.
My questions are:
Does anyone know why is this so? And how to fix it?
Furthermore, is the if (isFirst != 'True') clause the right way to init the ko view model?
You are dealing with an asynchronous operation (an Ajax request). These operations do not have return values. Therefore, this can never work:
ko.mapping.fromJS(search('someSearch', 'True'));
That's what the success callback is for. Incoming data can only be handled there.
function search(queryString, targetObservable) {
$.ajax({
type: 'POST',
url: 'url',
data: { 'searchQuery': queryString },
dataType: 'json',
success: function (dt) {
ko.mapping.fromJS(dt, targetObservable);
}
});
};
search('someSearch', PostsViewModel);

Categories