Ajax response how to access - javascript

I got this response from ajax
{
"laborCostIndex":0.0,
"laborDailyWage":0.0,
"laborHourlyWage":0.0,
"laborMonthlyWage":0.0,
"laborLeave":0.0,
"laborBonus":0.0,
"laborSSS":0.0,
"laborPagIbig":0.0,
"laborPhilHealth":0.0,
"laborEMP":0.0,
"laborTotalMonthlyRate":110.0,
"laborTotalDailyRate":4.230769230769231,
"laborTotalHourlyRate":0.5288461538461539
}
I'm trying to access the element inside through this:
response.laborCostIndex and response['laborCostIndex'] but seems doesn't work for me.
The ajax is from the xeditable here is the code:
UPDATE: posted the whole ajax
$('.laborCostIndex').editable({
pk: '1',
name: 'laborCostIndex',
url: '../BTool/edit_laborCostIndex.do',
validate: function( value ) {
if($.trim( value ) == '') {
return 'This field is required';
} else if( isNaN( value ) ) {
return 'Only accepts numbers';
}
},
params: function(params) {
var basicDailyWage = $(this).closest('td').next('td').find('a').text();
var pagIbig = $(this).closest('tr').find(':nth-child(11)').find('a').text();
var emp = $(this).closest('tr').find(':nth-child(13)').find('a').text();
var datas = new Array(basicDailyWage, pagIbig, emp);
params.pk = datas;
return params;
},
success: function(response, newValue) {
console.log( response );
console.log( response.laborCostIndex );
console.log( response['laborCostIndex'] );
}
});
Both results to undefined, I don't know why.

Try this in your success function
var obj = JSON.parse(response);
console.log( obj.laborCostIndex);

Related

Cannot get promise/ajax data to return to parent function

I searched for a long time and although there are many questions with similar keywords, none of them share the same intricacies, so let me explain my problem:
I have a function (getProjectData), that has to be called (it is a system wide thing) to get all data from a particular admin section of a cms. My problem comes from a conditional check, where if A one object is blank, where if B, it needs to contain the result of more than 1 ajax calls. The whole data object gets retuned in this function. Code so far:
function getProjectData() {
var code = "some id";
var frozen = true;
var obj = {
code: code,
frozen: true,
localData: "",
};
// here is the point where the object gets returned with a black localData
// or splits to get a few ajax calls
if ( !obj.frozen ) return obj;
else {
getLocalData ( code ).then( function ( data ) {
// ideally, here i would make the parent return obj, but this time with added localData data
obj.localData = data;
parent.return obj;
} );
}
}
function getLocalData ( code ) {
var promise = new Promise ( function ( resolve, reject ) {
var apiReq = "apiUrl";
var chartsReq = "anotherApiUrl";
var res;
$.when(
// api response
$.ajax({
url: apiReq + code,
type: "get",
success: function ( data ) {
return data;
},
error: function ( error ) {
return error;
}
}),
// another ajax call..
$.ajax({ ... }),
// another ajax call..
$.ajax({ ... })
).then(
function ( a, b, c ) {
data = {
response: a
...... for b and c
};
resolve ( data );
},
function ( error ) {
reject ( error );
}
);
} );
return promise.then(
function (data) {
return data;
},
function ( error ) {
console.log ( error );
}
);
}
My problem is that since (and i tried with other ways as well..) all the returns are in a function within other functions, there is no way to return the Obj object after the localData has been added.
I might have over-engineered it but i tried many different ways and since the getProjectData is called by a save button and values need to be returned rather than say, appended to the DOM, i am not sure what to do!
I know that in asynchronous requests, the function has to return before the result is available, where we would usually use callbacks, but a callback will not be able to return something. I could use synchronous requests but i know they are going to be deprecated..
Any ideas?
The correct way to call functions is listed below.
Sincerely I don't understand what you mean saying:
// ideally, here i would make the parent return obj, but this time with added localData data
Using the following way in the parent you should just call:
getProjectData.then(function(obj){ 
//... do whatever
});
JS:
function getProjectData() {
var code = "some id";
var frozen = true;
var obj = {
code: code,
frozen: true,
localData: "",
};
// here is the point where the object gets returned with a black localData
// or splits to get a few ajax calls
return new Promise(function(resolve, reject) {
if ( !obj.frozen )
resolve(obj);
else {
getLocalData ( code ).then( function ( data ) {
// ideally, here i would make the parent return obj, but this time with added localData data
obj.localData = data;
resolve(obj);
});
});
}
}
function getLocalData ( code ) {
var promise = new Promise ( function ( resolve, reject ) {
var apiReq = "apiUrl";
var chartsReq = "anotherApiUrl";
var res;
$.when(
// api response
$.ajax({
url: apiReq + code,
type: "get",
success: function ( data ) {
return data;
},
error: function ( error ) {
return error;
}
}),
// another ajax call..
$.ajax({ ... }),
// another ajax call..
$.ajax({ ... })
).then(
function ( a, b, c ) {
data = {
response: a
...... for b and c
};
resolve ( data );
},
function ( error ) {
reject ( error );
}
);
} );
return promise;
}

Pushing promise data to an array

I'm probably not using promises correctly, but I'm calling a service (defined in a separate factory) into my controller like so,
_.each( $scope.aap.idList, function( id ){
MyService.getItems( $stateParams.name, id ).$promise.then(
function( scan ){
if( scan.length !== 0){
addToList( scan );
}
})
});
var addToList = function ( item ) {
$scope.aap.scans.push( _.clone( item ) );
return $scope.aap.scans;
};
The service is defined as:
service.getItems = function ( name, id ) {
var Items = $resource( '/proj/rs/pr/elems/getItems', {
id: Id,
name: name
}, {
query: {
method: 'GET',
isArray: true,
transformResponse: function ( scans ) {
var items = angular.fromJson( scans );
_.each( items, function ( scanItem ) {
scanItem.checked = false;
} );
return items;
}
}
} );
return Items.query();
Now, in MyService.getItems I can add a console.log( scan ) and see the appropriate objects being passed through, but it won't add these items to my list. Is there some other way I should be going about this?

YUI datatable-sort not working

Hello I'm parsing some data from my database into a table using aui-datatable plugin however I would like to add some basic sorting in my columns. Bellow you may see the function "renderProducts" which renders the data-table. Furthermore bellow is a sample column object that is being passed into the table renderer.
var API= (function(Y){
var settings = {
serviceURL : null
};
var getServiceAttribute = function( attribute ) {
return '_openpimadmin_WAR_OpenTest_' + attribute;
}
var getServiceURL = function( service ) {
return settings.serviceURL + '&p_p_resource_id=' + service;
};
var service = function( service, dataSet, handlers ){
var serviceData = {};
var serviceHandlers = {
start : function(){},
success : function(){},
failure : function(){},
end : function(){}
};
for (prop in dataSet) {
serviceData[getServiceAttribute(prop)] = dataSet[prop];
}
for (prop in handlers) {
if ( serviceHandlers.hasOwnProperty(prop) && typeof handlers[prop] === 'function') {
serviceHandlers[prop] = handlers[prop];
}
}
Y.io(
getServiceURL( service ),
{
method : 'POST',
data : serviceData,
on : {
start : function( transactionID ) {
serviceHandlers.start(transactionID);
},
success : function( transactionID, response ) {
var parsed = Y.JSON.parse(response.responseText);
if (parsed.success === true){
serviceHandlers.success( transactionID, parsed );
} else {
console.log('Service [' + service + '] error: ' + parsed.error);
}
},
failure : function( transactionID, response ) {
serviceHandlers.failure( transactionID, response );
},
end : function( transactionID ) {
serviceHandlers.end( transactionID );
}
}
}
);
}
return {
services : {
getProducts : function( dataSet, handlers ){
dataSet = dataSet || {};
handlers = handlers || {};
service( 'getProducts', dataSet, handlers );
},
getProductsTableAttributeHeaders : function( dataSet, handlers) {
dataSet = dataSet || {};
handlers = handlers || {};
service( 'getProductsTableAttributeHeaders', dataSet, handlers );
},
},
views : {
renderProducts : function( el, columns, dataSet ) {
Y.one(el).get('childNodes').remove();
new Y.DataTable.Base({
columnset : columns,
recordset : dataSet,
width: '100%'
}).render(el);
}
},
get : function( prop ) {
return settings[prop];
},
set : function( options ) {
settings = Y.merge( settings, options );
}
};
})( YUI().use('node', 'io', 'aui-datatable', 'datatable-sort', function(Y){return Y;}) );
Column object:
Object {key: "name", label: "Όνομα", allowHTML: true, emptyCellValue: "<em>(not set)</em>", sortable: true}
The issue I'm facing is that sorting is nowhere to be seen, columns dont seem interactive and the user is not able to sort them, although the table is being rendered fine.
Thank you in advance.
PS: I'm new to YUI().
You need to make sure that sortable: true set for column that need sorting.
Here is a real world example with sorting feature
It seems this was the problem:
new Y.DataTable.Base({
columnset : columns,
recordset : dataSet,
width: '100%'
}).render(el);
Should have been like this:
new Y.DataTable({
columnset : columns,
recordset : dataSet,
width: '100%'
}).render(el);

Using aspect.around, but checking for methods calling each other

I would like to run some specific code around put() and add() for Dojo stores.
The problem I am having is that for JSON REST stores, in JsonRest.js add() is just a function that calls put():
add: function(object, options){
options = options || {};
options.overwrite = false;
return this.put(object, options);
},
So, if I use aspect.around() with add(), my code ends up being executed twice IF I apply my code to stores created with a store that implements add() as a stub to put().
Please note that I realise that most stores will do that. I just want my solution to be guaranteed to work with any store, whether there is method nesting or not.
Dojo's own Observable.js has the same problem. This is how they deal with it:
function whenFinished(method, action){
var original = store[method];
if(original){
store[method] = function(value){
if(inMethod){
// if one method calls another (like add() calling put()) we don't want two events
return original.apply(this, arguments);
}
inMethod = true;
try{
var results = original.apply(this, arguments);
Deferred.when(results, function(results){
action((typeof results == "object" && results) || value);
});
return results;
}finally{
inMethod = false;
}
};
}
}
// monitor for updates by listening to these methods
whenFinished("put", function(object){
store.notify(object, store.getIdentity(object));
});
whenFinished("add", function(object){
store.notify(object);
});
whenFinished("remove", function(id){
store.notify(undefined, id);
});
My question is: is there a simple, "short" way to change my existing code so that it checks if it's within a method, and avoid running the code twice?
I gave it a go, but I ended up with clanky, hacky code. I am sure I am missing something...
Here is my existing code:
topic.subscribe( 'hotplate/hotDojoStores/newStore', function( storeName, store ){
aspect.around( store, 'put', function( put ){
return function( object, options ){
return when( put.call( store, object, options ) ).then( function( r ) {
var eventName;
var identity = store.idProperty;
eventName = object[ identity ] ? 'storeRecordUpdate' : 'storeRecordCreate';
topic.publish( eventName, null, { type: eventName, storeName: storeName, objectId: r[ identity ], object: object }, false );
} );
}
});
aspect.around( store, 'add', function( add ){
return function( object, options ){
return when( add.call( store, object, options ) ).then( function( r ) {
var identity = store.idProperty;
topic.publish('storeRecordCreate', null, { storeName: storeName, storeTarget: storeTarget, objectId: r[identity], object: object }, false } );
});
}
});
});
This is my attempt...
What I don't really "get" about my attempt is whether it's 100% safe or not.
If store.add() is called twice in a row, is is ever possible that inMethod is set to true by the first call, and that the second add() call then finds it already set to true because the first one hasn't managed to set it to false yet?
This would only really be possible if nextTick() is called in between the two calls I assume?
Or am I just completely confused by it all? (Which is very possible...)
topic.subscribe( 'hotplate/hotDojoStores/newStore', function( storeName, store ){
var inMethod;
aspect.around( store, 'put', function( put ){
return function( object, options ){
if( inMethod ){
return when( put.call( store, object, options ) );
} else {
inMethod = true;
try {
return when( put.call( store, object, options ) ).then( function( r ) {
var eventName;
var identity = store.idProperty;
eventName = object[ identity ] ? 'storeRecordUpdate' : 'storeRecordCreate';
topic.publish( eventName, null, { type: eventName, storeName: storeName, objectId: r[ identity ], object: object }, false );
});
} finally {
inMethod = false;
}
}
}
});
aspect.around( store, 'add', function( add ){
return function( object, options ){
if( inMethod ){
return when( add.call( store, object, options ) );
} else {
inMethod = true;
try {
return when( add.call( store, object, options ) ).then( function( r ) {
var identity = store.idProperty;
topic.publish('storeRecordCreate', null, { type: 'storeRecordCreate', storeName: storeName, objectId: r[identity], object: object }, false );
});
} finally {
inMethod = false;
}
}
}
});
aspect.around( store, 'remove', function( remove ){
return function( objectId, options ){
return when( remove.call( store, objectId, options ) ).then( function( r ) {
topic.publish('storeRecordRemove', null, { type: 'storeRecordRemove', storeName: storeName, objectId: objectId }, false );
});
};
});
});

Qunit unit test error , on jQuery ajax

I have written unit test for ajax suing Qunit, but getting error like
Error: assertion outside test context, was .success#http://test.loc/assets/test/widget-add-or-edit-test.js:227
b.Callbacks/c#http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js:3
b.Callbacks/p.fireWith#http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js:3
k#http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js:5 .send/r#http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js:5
Source:
http://code.jquery.com/qunit/qunit-1.11.0.js:899
my test code is
test( "Widget.updateAxisTypeAjax x", function() {
stop();
Widget.updateAxisTypeAjax( {
axis : 'x' ,
x_id : 179,
y_id : 175
} ,{
success : function( response ){
ok( true, "updateAxisTypeAjax Success PASS!");
equal( typeof response ,
"object" ,
"updateAxisTypeAjax response is json valid object !"
);
equal( typeof response == "object" &&
( "average" in response ) &&
("is_datetime" in response) ,
true ,
"updateAxisTypeAjax average check PASS !"
);
} ,
complete : function(){
ok(true, "updateAxisTypeAjax completed PASS!");
start();
}
});
});
and Widget.updateAxisTypeAjax is
Widget.updateAxisTypeAjax = function( data_obj, callbacks ){
data_obj = jQuery.extend( data_obj ,{
action : 'update_axis'
});
Widget.ajax( 5 )
.data( data_obj )
.callbacks( callbacks )
.fire();
}
and Widget.ajax is :
var Widget = Widget || {} ;
function _WidgetAjax( type ){
var loader = $('#series_loader');
this.ajaxUrl = '/dashboard/charts/ajax/' + ( type || 1 ) ;
this.ajaxSettings = {
url: this.ajaxUrl ,
type:"GET",
data :{} ,
complete : function(){ // always
loader.hide();
}
};
// show ajax loading
loader.show();
this.data = function( data ){
jQuery.extend( this.ajaxSettings, { data: data } );
return this;
}
this.callbacks = function( callbacks ){
jQuery.extend( this.ajaxSettings, callbacks || {} );
return this;
}
this.success = function( func ){
if ( jQuery.isFunction( func ) ){
jQuery.extend( this.ajaxSettings, { success: func } );
}
return this;
};
this.fire = function(){
return $.ajax( this.ajaxSettings );
};
};
Widget.ajax = function( type ){
return new _WidgetAjax( type );
};
Please help me fix this unit test error !
You're testing an asynchronous function, so you need to use the async features in QUnit.
Instead of test you should be using asyncTest
Here is the documentation.
Note that you have to tell QUnit how many assertions to expect when doing async tests.
asyncTest( "Widget.updateAxisTypeAjax x", 4, function() {
stop();
Widget.updateAxisTypeAjax( {
axis : 'x' ,
x_id : 179,
y_id : 175
} ,{
success : function( response ){
ok( true, "updateAxisTypeAjax Success PASS!");
equal( typeof response ,
"object" ,
"updateAxisTypeAjax response is json valid object !"
);
equal( typeof response == "object" &&
( "average" in response ) &&
("is_datetime" in response) ,
true ,
"updateAxisTypeAjax average check PASS !"
);
} ,
complete : function(){
ok(true, "updateAxisTypeAjax completed PASS!");
start();
}
});
});
Should probably work. This shouldn't be too hard to fix!

Categories