Parse JSON array with AJAX from PHP - javascript

I am having trouble making an PHP API to get data from MYSQL and parse JSON. I have a demo app (hiApp) and comes with some JSON files inside a folder.
The demo JSON file is like this:
{ "err_code": 0, "err_msg": "success", "data": [{"nickname":"Joao","location":"I.13"},{"nickname":"Victor","location":"2811"}]}
This what my contacts.php is returning:
[{"nickname":"Joao","location":"I.13"},{"nickname":"Victor","location":"2811"}]
My contacts.php api looks like this:
…
…
$result = mysql_query("select * from sellers", $db);
$json_response = array();
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$row_array['nickname'] = $row['first_name'];
$row_array['location'] = $row['territory'];
array_push($json_response,$row_array);
}
echo json_encode($json_response);
?>
The js file to parse JSON, looks like this:
define(['utils/appFunc',
'i18n!nls/lang',
'components/networkStatus'],function(appFunc,i18n,networkStatus) {
//var apiServerHost = window.location.href;
var xhr = {
search: function(code, array){
for (var i=0;i< array.length; i++){
if (array[i].code === code) {
return array[i];
}
}
return false;
},
getRequestURL: function(options){
//var host = apiServerHost || window.location.host;
//var port = options.port || window.location.port;
var query = options.query || {};
var func = options.func || '';
var apiServer = 'api/' + func + '.php' +
(appFunc.isEmpty(query) ? '' : '?');
var name;
for (name in query) {
apiServer += name + '=' + query[name] + '&';
}
return apiServer.replace(/&$/gi, '');
},
simpleCall: function(options,callback){
options = options || {};
options.data = options.data ? options.data : '';
//If you access your server api ,please user `post` method.
//options.method = options.method || 'GET';
options.method = options.method || 'POST';
if(appFunc.isPhonegap()){
//Check network connection
var network = networkStatus.checkConnection();
if(network === 'NoNetwork'){
hiApp.alert(i18n.error.no_network,function(){
hiApp.hideIndicator();
hiApp.hidePreloader();
});
return false;
}
}
$$.ajax({
url: xhr.getRequestURL(options) ,
method: options.method,
data: options.data,
success:function(data){
data = data ? JSON.parse(data) : '';
var codes = [
{code:10000, message:'Your session is invalid, please login again',path:'/'},
{code:10001, message:'Unknown error,please login again',path:'tpl/login.html'},
{code:20001, message:'User name or password does not match',path:'/'}
];
var codeLevel = xhr.search(data.err_code,codes);
if(!codeLevel){
(typeof(callback) === 'function') ? callback(data) : '';
}else{
hiApp.alert(codeLevel.message,function(){
if(codeLevel.path !== '/')
mainView.loadPage(codeLevel.path);
hiApp.hideIndicator();
hiApp.hidePreloader();
});
}
}
});
}
};
return xhr;
});
I know the error is in the way contacts.php is displaying the JSON results or I need to change something in the js file.
Thanks for the help.

Based on your comments above I've tried to rewrite a solution keeping the same structure, but removing the unnecessary things; this is what the code may look like. Note that there are no references to err_code and err_msg peoperties, and the callback is called directly on data variable.
define(['utils/appFunc',
'i18n!nls/lang',
'components/networkStatus'],function(appFunc,i18n,networkStatus) {
//var apiServerHost = window.location.href;
var xhr = {
getRequestURL: function(options){
//var host = apiServerHost || window.location.host;
//var port = options.port || window.location.port;
var query = options.query || {};
var func = options.func || '';
var apiServer = 'api/' + func + '.php' +
(appFunc.isEmpty(query) ? '' : '?');
var name;
for (name in query) {
apiServer += name + '=' + query[name] + '&';
}
return apiServer.replace(/&$/gi, '');
},
simpleCall: function(options,callback){
options = options || {};
options.data = options.data ? options.data : '';
//If you access your server api ,please user `post` method.
//options.method = options.method || 'GET';
options.method = options.method || 'POST';
if(appFunc.isPhonegap()){
//Check network connection
var network = networkStatus.checkConnection();
if(network === 'NoNetwork'){
hiApp.alert(i18n.error.no_network,function(){
hiApp.hideIndicator();
hiApp.hidePreloader();
});
return false;
}
}
$$.ajax({
url: xhr.getRequestURL(options) ,
method: options.method,
data: options.data,
success:function(data){
data = data.length > 0 ? JSON.parse(data) : [];
if (typeof(callback) === 'function' && data !== undefined)
callback(data);
}
});
}
};
return xhr;
});
Then you may call it this way, using directly response var, which now contains the parsed data array:
loadContacts: function() {
if(VM.module('contactView').beforeLoadContacts()) {
xhr.simpleCall({
query: { callback: '?' },
func: 'contacts'
}, function (response) {
if (response !== undefined) {
VM.module('contactView').render({
contacts: response
});
}
});
}
}
Also, you would have to add
header('Content-Type: application/json');
before your PHP echo line in order to be able to parse it in JS.

Ok, many thanks Andrea, looks like there is something else that I'm missing because the results from the contacts.php and the initial contacts.php file is the same in my browser:
[{"nickname":"Joao","location":"I.13"},{"nickname":"Victor","location":"2811"}]
It works just fine if I use the initial contacts.php that only has pure json data like above, but if I switch to my api it stops working.
Also it stops working if I use this in the initial contacts.php:
<?php
$myString = '[{"nickname":"Joao","location":"I.13"},{"nickname":"Victor","location":"2811"}]';
echo $myString;
?>
I'll keep looking, but thanks to you I'm one step ahead.

Related

How to add dynamically attribute value using Jquery?

I have logic where i am trying to add host url dynamically so it work in all env based on hosst, so below trying to find a file that is there in host but its never going into $.each statement , if call url directly http://18.35.168.87:6000/Sdk/wrapper-sdk/client/out.json it worked and rendered data, any idea what could have wrong in below code to achieve this task ?
main.js
function myFunction(val) {
var url = "../../wrapper-sdk/" + client + "/out.json";
if (window.location.hostname.indexOf("localhost") !== -1 ||
window.location.host.indexOf("localhost") !== -1) {
var scripts = document.getElementsByTagName('script');
var host = '';
$.each(scripts, function (idx, item) {
if (item.src.indexOf('Sdk/wrapper-sdk') !== -1 && (item.src.indexOf('out.json') !== -1)) {
host = item.src.split('?')[0];
host = host.replace('wrapper-sdk/' + client + '/out.json', '');
}
});
url = url.replace('../../', host);
}
$.ajax({
url: url + "?no_cache=" + new Date().getTime(),
dataType: "json",
"async": false,
success: function (data) {
console.log(data);
},
error: function () {
console.log('error while accessing api.json.')
}
});
}
I would suggest breaking up some of your checks into their own function. Makes it just a bit easier to follow the logic.
function validIp(str) {
var parts = str.split(".");
var result = true;
$.each(parts, function(i, p) {
if (parseInt(p) > 0 && parseInt(p) < 255) {
result = result && true;
}
});
return result;
}
function checkLocalUrl(str) {
var result = 0;
if (str.indexOf("localhost") >= 0) {
result = 1;
}
if (validIp(str)) {
result = -1;
}
/*
0 = Some Domain or Host Name, not LocalHost
1 = LocalHost
-1 = IP Address
*/
return result;
}
function changeSources(client) {
if (checkLocalUrl(window.location.hostname) || checkLocalUrl(window.location.host) {
var scripts = $("script");
var host = '';
scripts.each(function(i, el) {
var src = $(el).attr("src");
var nUrl = new URL(src);
var pro = nUrl.protocol;
var hn = nUrl.hostname;
if (nUrl.pathname.indexOf('/Sdk/wrapper-sdk') == 0 && nUrl.pathname.indexOf('out.json') > 0) {
host = pro + "://" + hn + "/wrapper-sdk/" + client + "/out.json";
}
$.ajax({
url: host
data: { no_cache: new Date().getTime() },
dataType: "json",
async: false,
success: function(data) {
console.log(data);
},
error: function() {
console.log('error while accessing api.json.')
}
});
});
}
}
}
See also: new URL()
You can send a string to checkLocalUrl() and it will return 1 or true if it's potentially a localhost URL. It will return 0 or false if it's any other domain pattern or -1 or false if it's an IP address.
In changeSources() we can use this to check for local urls and perform the AJAX you defined.

Nodejs + Q promise + method return based on url type

I am using node js for backend, also using q promise package.
Question : I am trying to get third party product details.
1. www.abcd.com 2. www.xyz.com - this method i handle in backend.
Possible url:
localhost:8080/search?type="abcd";
localhost:8080/search?type="xyz";
localhost:8080/search;
If the above URL type is abcd means need to search some different thridparty(www.abcd.com) http url;
If the above URL type is xyz means need to search some other different thridparty(www.xyz.com) http url
If the above URL didn't get type means need to search www.abcd.com if the result found means then return response, if result not found means need to call www.xyz.com url and then return response. (Note - here two third party api need to call)
Code:
router.get('/search', function(req, res, next) {
if (!( typeof req.query === 'undefined' || req.query === null || req.query == "")) {
var type = req.query;
}
var spec = {
resp : {}
};
Q(spec).then(function(spec) {
var deferred = Q.defer();
var optionsget = {
host : 'abcd.com',
method : 'GET'
};
var reqGet = https.request(optionsget, function(res) {
var getProductInfo = '';
res.on('data', function(d) {
getProductInfo += d;
});
res.on('end', function() {
if (( typeof message == 'undefined') && (!( typeof items === 'undefined' || items === null))) {
spec.resp.list = items;
deferred.resolve(spec);
} else {
spec.resp.message = message;
deferred.reject(spec);
}
});
});
reqGet.end();
reqGet.on('error', function(e) {
console.log(e);
deferred.reject(spec);
});
return deferred.promise;
}).then(function(spec) {
var deferred = Q.defer();
var optionsget = {
host : 'xyz.com',
method : 'GET'
};
var reqGet = https.request(optionsget, function(res) {
var getProductInfo = '';
res.on('data', function(d) {
getProductInfo += d;
});
res.on('end', function() {
if (( typeof message == 'undefined') && (!( typeof items === 'undefined' || items === null))) {
spec.resp.list = items;
deferred.resolve(spec);
} else {
spec.resp.message = message;
deferred.reject(spec);
}
});
});
reqGet.end();
reqGet.on('error', function(e) {
console.log(e);
deferred.reject(spec);
});
return deferred.promise;
}).then(function(spec) {
spec.resp.status = 'Success';
res.send(spec.resp);
}).fail(function(spec) {
spec.resp.status = 'Error';
res.send(spec.resp);
});
});
I this is chilly question. I understand need to check the type and implement. I thought we need to add some different function for both (abcd and xyz) then can call that method based on type.
Please suggest to good way.

jQuery.post() dynamically generated data to server returns empty response

I'm generating a series of variables in a loop (using JS), and I'm assigning them an .id and a .name based on the current index. At each loop I'm sending a request to the server using jQuery.post()method, but the returning response is just an empty variable.
Here's the code:
JavaScript
for ( var index = 0; index < 5; index++ ) {
var myVar = document.createElement('p');
myVar.id = 'myVarID' + index;
myVar.name = 'myVarName' + index;
//Send request to server
$(document).ready(function(){
var data = {};
var i = 'ind';
var id = myVar.id;
var name = myVar.name;
data[id] = name;
data[i] = index;
$.post("script.php", data, function(data){
console.log("Server response:", data);
});
});
}
PHP
<?php
$index = $_POST['ind'];
$myVar = $_POST['myVarID'.$index];
echo $myVar;
?>
Response: Server response: ''
If I instead set a static index in JS code, getting rid of the loop, so for example:
var index = 0;
I get the expected result: Server response: myVarName0
Why is this happening? And how can I solve it?
Assuming the php file is in order. I use this:
function doThing(url) {
getRequest(
url,
doMe,
null
);
}
function doMe(responseText) {
var container = document.getElementById('hahaha');
container.innerHTML = responseText;
}
function getRequest(url, success, error) {
var req = false;
try{
// most browsers
req = new XMLHttpRequest();
} catch (e){
// IE
try{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
// try an older version
try{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function () {};
if (typeof error!= 'function') error = function () {};
req.onreadystatechange = function(){
if(req .readyState == 4){
return req.status === 200 ?
success(req.responseText) : error(req.status)
;
}
}
var thing = "script.php?" + url;
req.open("GET", thing, true);
req.send(null);
return req;
}
then use it like this:
doThing("myVarID="+myVar.id+"&i="+index);
also, you will have to change your PHP to something like this:
<?php
$index = $_GET['ind'];
$myVar = $_GET['myVarID'.$index];
echo $myVar;
?>
Obviously this code needs to be edited to suit your own needs
the function doMe is what to do when the webpage responds, in that example I changed the element with the id hahaha to the response text.
This won't win you any prizes but it'll get the job done.
Solution
It is working fine removing:
$(document).ready()
Working code
for ( var index = 0; index < 5; index++ ) {
var myVar = document.createElement('p');
myVar.id = 'myVarID' + index;
myVar.name = 'myVarName' + index;
//Send request to server
var data = {};
var i = 'ind';
var id = myVar.id;
var name = myVar.name;
data[id] = name;
data[i] = index;
$.post("script.php", data, function(data){
console.log("Server response:", data);
});
}

Modify data before jquery ajax submit

I have a form that is used by admin to modify user details and before submitting I want to modify the structure of the data ( flat array) to be a json objects with some level of hierarchy.
User = { username: 'myUserName' , roles : [ {role : 'ADMIN'},{role: USER} ], etc..}
so to do this in my client web page I've done this :
$("#submitUpdate").click(function() {
var dataAsJson = JSON.stringify(function(){
//user
var o = {};
//spring token
var tk = {};
//var usrname
var un={};
var formData = $("#updateForm").serializeArray();
$.each(formData, function(k, v) {
if (o[v.name] !== undefined) {
if (!o[v.name].push) {
o[v.name] = [ o[v.name] ];
}
o[v.name].push(v.value || '');
} else {
if (v.name === 'userRoles') {
if (v.value !== undefined) {
var a = [];
$.each(v.value.split(','), function(i, rl) {
var r = {};
r.role = rl;
a.push(r);
});
o[v.name] = a;
} else
o[v.name] = [];
} else if (v.name === '_csrf') {
tk[v.name] = v.value;
} else if (v.name === '_username') {
un[v.name] = v.value || '';
} else
o[v.name] = v.value || '';
}
});
var obj = [];
obj.push(tk); obj.push(un); obj.push(o);
return obj;
}());
$("#updateForm").ajaxSubmit({
url : "${userUpdateCtx}",
data: dataAsJson,
beforeSubmit : function(formData, jqForm, options) {
},
success : function(msg) {
$table.bootstrapTable('refresh');
},
error : function(e) {
showError(e);
}
});
});
the problem is that the for is never gets submit and I get ERROR 400
HTTP Status 400 -
Type Report Status
message
Description request sent by the client was syntactically incorrect.
I've tried to put the processing code inside beforeSubmit and return the string JSON.stringify(obj) but this don't seem to work either.
how could I make this work ?.
EDIT
Thanks to comments below I've fixed the dataAsJson but still having the same error, the dump of the request looks like this (cut it off too long ):
URL de la requête : http://localhost:8080/WebMarket/admin/users/update?_csrf=9323a5ac-9a49-436f-a799-89b4814fb309&enabled=1&firstName=Steve&lastName=Jobs&_username=manager&username=manager&password=%242a%2410%24BVRCqPA6.qdvs%2Fma0uH6Here4ozKudoHyH2OFz2xc3.FfwL%2FEyXz6&userRoles=ROLE_MANAGER&0=%5B&1=%7B&2=%22&3=_&4=c&5=s&6=r&7=f&8=%22&9=%3A&10=%22&11=9&12=3&13=2&14=3&15=a&16=5&17=a&18=c&19=-&20=9&21=a&22=4&23=
Méthode de la requête : POST
Code d'état : HTTP/1.1 400 BAD REQUEST

restructure string in javascript

I have this string in which i need to re-structure using JavaScript.
Label=11121212&TopicArn=test&AWSAccountId.member.1=YYYYYYY&ActionName.member.1=createTopic&Action=AddPermission&Version=2010-03-31&AWSAccessKeyId=XXXXXXXXX&SignatureVersion=2&SignatureMethod=HmacSHA1&Timestamp=2012-05-02T16%3A06%3A09.000Z&Signature=C3uIh%2Bz%2Fik
For this example, AWSAccessKeyId should be the first part of the string and label should be 2nd last. There are others as well, similar to this.
Expected output --AWSAccessKeyId=XXXXXXXXX&AWSAccountId.member.1=YYYYYYYYY&Action=AddPermission&ActionName.member.1=Publish&Label=ios-sns-permission-label&Signature=dEaNL0ibP5c7xyl4qXDPFPADW0meoUX9caKyUIx1wkk%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2012-05-02T00%3A51%3A23.965Z&TopicArn=arn%3Aaws%3Asns%3Aus-east-1%3A335750469596%3AiOSGoesWooooo-1335919882&Version=2010-03-31
Code that creates this incorrect string
exports.generatePayload = function(params, accessKeyId, secretKey, endpoint) {
var host = endpoint.replace(/.*:\/\//, "");
var payload = null;
var signer = new AWSV2Signer(accessKeyId, secretKey);
params = signer.sign(params, new Date(), {
"verb" : "POST",
"host" : host,
"uriPath" : "/"
});
var encodedParams = [];
for(var key in params) {
if(params[key] !== null) {
encodedParams.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
} else {
encodedParams.push(encodeURIComponent(key));
}
}
payload = encodedParams.join("&");
return payload;
}
I tried putting this in an array and restructure it but it didn't work for me.
Please advice how this can be done easily using JavaScript
exports.generatePayload = function(params, accessKeyId, secretKey, endpoint) {
var host = endpoint.replace(/.*:\/\//, "");
var payload = null;
var signer = new AWSV2Signer(accessKeyId, secretKey);
params = signer.sign(params, new Date(), {
"verb" : "POST",
"host" : host,
"uriPath" : "/"
});
var encodedParams = [];
if(params["AWSAccessKeyId"] != null)
{
encodedParams.push(encodeURIComponent("AWSAccessKeyId") + "=" + encodeURIComponent(params["AWSAccessKeyId"]));
}
if(params["AWSAccountId.member.1"] != null)
{
encodedParams.push(encodeURIComponent("AWSAccountId.member.1") + "=" + encodeURIComponent(params["AWSAccountId.member.1"]));
}
//other_ifs_for_param_keys_here
payload = encodedParams.join("&");
return payload;

Categories

Resources