split ajax json response errors in each field - javascript

i used till now AJAX post with normal dataType 'html' , now i convert it and using dataType 'json' ,
Now before i used json i split response errors with for each span next to the input field .
this is my old ajax succses split errors code using normal datatype 'html' :
success:
function(data){
var data_array = split('*');
for(var i=0; i<data_array.length-1; i++)
{
messgae_array = data_array[i].split(':');
$("#"+messgae_array[0]+"_error").html(messgae_array[1]);
$("#"+messgae_array[0]).css({"border":"1px solid red"});
}
}
this is my input on the form
<input type="text" id="uname" name="uname" value="" class="inplaceError" />
<span id="uname_error"></span>
i have more inputs i puted just ex how it look..
so every input i have span that holds the errors from the ajax response.
and now the problem is my old code know handle html response and not json response , i am javascript/ajax/json newbie , and i dont know how to change the split code so work with json response and not normal html response , any help please?
Edit:
i fire the errors like this :
if(isset($_POST['p']) && !empty($_POST['p']))
{
if($password == $retype)
{
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
// Create salted password (Careful with the chilli)
$password = hash('sha512', $password.$random_salt);
}
else
{
$message['password']=' password not match';
}
and so on .
$message['email']=' wrong email';
and my foreach json array for the errors :
foreach($message as $key => $val) {
$return = array('error' => $key, 'message' => $val );
echo json_encode($return);
}
so somthing is wrong here with the foreach for the errors its fire wrong as the ajax response code any idea?

You should not have to split strings in your data. If it is in the correct JSON format, you can access it easily using object notation (also possible via array notation):
var json = '{
"someVar":true,
"error":"my fatal error message"
}';
var obj = JSON.parse(json);
alert(obj.error);
This is why JSON was created, for ease of access and use. If you're still going to edit and split strings manually to read data from your JSON, you're doing it wrong.
EDIT:
Use nested json, if you need to identify and organise your messages.
var json = "errors": [{
"id": "001",
"field": "textfield1",
"message": "message1."
},
{
"id": "002",
"field": "textfield2",
"message": "message2."
}];
var obj = JSON.parse(json);
You can now apply styles to these fields, and display the messages:
foreach(obj.errors as err) {
$("#"+err.field).html(err.message);
$("#"+err.field).css({"border":"1px solid red"});
}

success:function(data)
{
// consider your data is like this JSON string
// var data= [{"error":"uname","message":" wrong pass."},{"error":"email","message":" wrong name"}];
// instead of this
// var data_array = split('*');
// use this
//change your json parser to this
var data_array = JSON.parse(data);
for (var i in data_array )
{
$("#"+data_array[i].error+"_error").html(data_array[i].message);
$("#"+data_array[i].error).css({"border":"1px solid red"});
}
}

Related

Ajax read PHP generated json

So I want to send a json to an ajax call but I don't know how to read the json when is sent. And also my json looks strange because of the backslashes...
This is my ajax:
function find(){
var type = $('#object_type').val();
$.ajax({
type : 'POST',
url : 'get_user.php',
data : {
'type' : type
},
dataType : 'json',
error : function(response){
alert('SOMETHING WENT WRONG');
},
success : function(response){
This is what I get as a response:
"[{\"name\":\"Test\",\"link\":\"test.php\"},{\"name\":\"Test2\",\"link\":\"test2
.php\"}]"
}
});
}
This is my PHP function:
$type = $_POST['type'];
$user_array;
$user = mysqli_query($conn, "SELECT name,link FROM user WHERE `type` LIKE '%".$type."%'") or die();
while ($row = mysqli_fetch_array($user, MYSQLI_ASSOC)) {
$row_array['name'] = $row['name'];
$row_array['link'] = $row['link'];
array_push($user_array, $row_array);
}
mysqli_close($conn);
$result = json_encode($user_array, 128);
echo json_encode($result);
First change that you should make :
You don't need to encode two times
$result = json_encode($user_array, 128);
echo json_encode($result);
should be
$result = json_encode($user_array, 128);
echo $result;
Now the response should look like
[{"name":"Test","link":"test.php"},{"name":"Test2","link":"test2
.php"}]
which is a valid Javascript Array and can be accessed using following code :
var len = response.length;
for(i=0;i<len;i++){
console.log(response[i].name);
console.log(response[i].link);
}
As provided in techierishi's answer. Do not encode your response twice. Just do
echo $result;
The JSON should be valid and parsed, why?
json_encode is used on a valid PHP array returned from a MySQLi query.
dataType is used, explicitly forcing jQuery to JSON.parse the response and no errors where raised during that process.
The JSON that is returned has the following structure
ROOT
ARRAY
ARRAY OBJECT
OBJECT PROPERTY
To address something like that:
root[array index].property
Will give you the array's value, which is an object. That object has multiple properties.
[] means array
{} means object
So [{name:"value 1"},{name:"value 2"}] is actually
ARRAY
[0].name = value 1
[1].name = value 2
So retrieving information like name from your JSON will be:
response[0].name; // = test

Properly returning a JSON object with an embedded JS function

Updated Post
I have a solution for that problem which works with me so far (only tested on Firefox).
My main goal was to dynamically update a Flot graph with Ajax. I also need to dynamically update the axis styles and you can do this by the tickFormatter option. To avoid the problems I previously had, I simply insert the desired return string in the PHP array and JSON encode that array. After returned to the Ajax function I create a new function using the javascript Function() constructor (Link). I hope this helps someone.
Ajax
$.ajax({
url: 'someControllerWhichCreatesJSONdata',
data: 'some Value',
type: 'post',
cache: false,
datatype: 'json'
})
.success(function(data) {
var datas = data[0]; // fetch data array
var options = data[1]; // fetch options array
var xReturn = options.xaxes[0].tickFormatter; // fetch return string
var yReturn = options.yaxes[0].tickFormatter;
var xFunc = new Function("val", "axis", xReturn); // create function
var yFunc = new Function("val", "axis", yReturn);
options.xaxes[0].tickFormatter = xFunc; // update tickFormatter with function
options.yaxes[0].tickFormatter = yFunc;
$.plot($("#yw0"), datas, options);
})
.error(function(data) {
$("#error").html(data.responseText); // show error in separate div
});
PHP array
$options = array(
'legend' => array(
'position' => 'nw',
'show' => true,
'margin' => 10,
'backgroundOpacity' => 0.5
),
'grid' => array(
'clickable' => true,
'hoverable' => true
),
'pan' => array('interactive' => true),
'zoom' => array('interactive' => true),
'axisLabels' => array('show' => true),
'xaxes' => array(
array(
'axisLabel' => 'someUnit',
'tickFormatter' => 'return "foo bar"' // enter whatever return value you need
)
),
'yaxes' => array(
array(
'axisLabel' => 'someUnit',
'tickFormatter' => 'return "foo bar"'
)
)
);
I skip the data array as it looks similar. Both arrays get combined and JSON encoded.
public function actionSomeControllerWhichCreatesJSONdata() {
$returnArray = array($data, $options);
echo json_encode($returnArray);
return true;
}
The resulting array looks like the one I've posted in the bottom of this post.
Original Post
I'm trying for hours now, but I can't get this to work.
I have an Ajax request which gets a JSON object as return value on success. This works fine as long as I don't use a JS function in my JSON array. So my JSON array looks as follows (after json_encode):
[{
"data": [{
{1,2},
{3,4},
}],
"function": "function(){return \"foo bar\";}"
}]
In order to get rid of the "'s in the function string. I use str_replace and replace the quoted string with an unquoted one. This then looks like so:
[{
"data": [{
{1,2},
{3,4},
}],
"function": function(){return "foo bar";}
}]
The plain json_encode works fine and my Ajax function reads it as a JSON object. After I replace the string it turns out that the return value is no longer a JSON object but a plain text string. I've tried to parse the string again with jquery.parseJSON() but this results in the syntax error:
SyntaxError: JSON.parse: unexpected keyword at line 1 column 396 of the JSON data
Ajax function:
$.ajax({
url: 'someControllerWhichCreatesJSONdata',
data: 'some Value',
type: 'post',
cache: false,
datatype: 'json' // or text when trying to parse
})
.success(function(data) {
console.log(data);
var dat = jQuery.parseJSON(data); // trying to parse (only when dataType: "text")
var datas = dat[0]; // or data[0] when datType = json
var options = dat[1]; // ---
$.plot($("#yw0"), datas, options); // trying to update a FLOT window
})
.error(function(data) {
console.log("error");
$("#error").html(data.responseText); // show error in separate div
});
So when using this function and setting the return type to "json", it produces an error. If the return type is "text" and I try to parse the string I get the error above. Is there any solution for this problem or am I doing something completely wrong?
Thank's for your help!
UPDATE
Sorry of course my JSON data is not valid! As I said, my JSON object gets created by json_encode which I guess should get the syntax right. The plain array after son_encode looks like:
[[{
"data":[[0.0042612,0.0042612]],
"label":"WISE.W3: Cutri et. al 2012",
"lines":{"show":false},
"points":{"show":true,"radius":3}}],
{
"legend": {
"position":"nw",
"show":true,
"margin":10,
"backgroundOpacity":0.5},
"grid": {
"clickable":true,
"hoverable":true},
"pan":{"interactive":true},
"zoom":{"interactive":true},
"axisLabels":{"show":true},
"axisLabel": {
"unit":"Jy",
"id":null,
"name":null},
"tickFormatter":"$tickFormatter$",
"position":"right"
}]
and after str_replace I get
[[{
"data":[[0.0042612,0.0042612]],
"label":"WISE.W3: Cutri et. al 2012",
"lines":{"show":false},
"points":{"show":true,"radius":3}}],
{
"legend": {
"position":"nw",
"show":true,
"margin":10,
"backgroundOpacity":0.5},
"grid":{"clickable":true,"hoverable":true},
"pan":{"interactive":true},
"zoom":{"interactive":true},
"axisLabels":{"show":true},
"axisLabel":{"unit":"Jy","id":null,"name":null},
"tickFormatter":function(val, axis){return val.toExponential(2)},
"position":"right"
}]
Adeno pointed it out already, your JSON syntax is not valid.
Please try to validate your JSON with a linter, like http://jsonformatter.curiousconcept.com/
This is a bit better:
[{"data":[["1","2"],["3","4"]],"function":"function(){return \"foo bar\";}"}]
And the other thing is: you should not manually deserialize the JSON. All newer versions of jQuery will automatically deserialize JSON based on the response's content-type header.
You already set dataType to json for the ajax request.
The response is JSON and will be de-serialized.
So you can directly use
.success: function(response) {
console.log(response.data);
console.log(response.function);
}
Answer for the questions/issue from the comments:
Now you created invalid JSON again, because "tickFormatter" : function(val, axis){return val.toExponential(2)}, misses the quotes around the function string.
Before you insert the string with str_replace(), you need to take care of escaping and quoting.
You may need a little helper function, which properly escapes a string - to be valid JSON.
you need to use str_replace() correctly: not replacing the outer quotes, just the inner $tickFormatter$.
Wait.. i will provide an example:
// we already have an array, which is JSON encoded
// now you want to insert additional JSON content.
// therefore we use a token replace approach.
// valid JSON - with $token$
$json = '[{"data":[["1","2"],["3","4"]],"tickFormatter":"$tickFormatter$"}]';
// the (future) javascript function is a string.
// it's not properly escaped or quoted to be JSON
// this allows for copy and pasting JS into PHP
$unescaped_functionString = 'function(){return "foo bar";}';
// in order escapre properly, we need a json escaping helper
/**
* #param $value
* #return mixed
*/
function escapeJsonString($value) { # list from www.json.org: (\b backspace, \f formfeed)
$escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c");
$replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b");
$result = str_replace($escapers, $replacements, $value);
return $result;
}
// then we escape the function string
$functionString = escapeJsonString($unescaped_functionString);
// now its ready to be inserted into the existing JSON,
// where token $tickFormatter$ is defined
// the token must be in single quotes. you replace just the $token$ and not "$token$".
$json = str_replace('$tickFormatter$', $functionString, $json);
echo $json;
// The result is valid JSON again:
// [{"data":[["1","2"],["3","4"]],"tickFormatter":"function(){return \"foo bar\";}"}]
Next step:
The ajax request is made, the json data is transferred to the client and you want to execute the function you passed in.
So the new question is "How to call/exec a JavaScript function from a string - without using eval?"
In general tunneling is a bad practice, see: Is it valid to define functions in JSON results?
Anyway, there a different ways to do this:
Referencing: http://everythingfrontend.com/posts/studying-javascript-eval.html
eval() - evil, but works.
setTimeout()
setTimeout(" function ", 0);
new Function()
var codeToExecute = "My.Namespace.functionName()";
var tmpFunc = new Function(codeToExecute);
tmpFunc();
document.write
document.write('<script> JS </script>')
data URI
var s = document.createElement('script');
s.src = 'data:text/javascript,' + encodeURIComponent('alert("lorem ipsum")')
document.body.appendChild(s);
JSON cannot contain functions like this.
You can however use Javascript to inject the function into the DOM, so what you want to do is skip the str_replace part and simply create a <script type="text/javascript"></script> element in the DOM and insert the data.function property into there.

How could I JSON.parse nested object inside array

I'm trying to pass this structure on a PHP/Ajax response:
{"asn":"167", "jte":"[[1381547700000,0.0], [1381548600000,0.0]]", "visitas":"[{x:1380596400000,text:'HELLO WORLD.',title:'X'}]"}
But JSON.parse returns an error.
SyntaxError: JSON.parse: expected property name or '}'
Without the "visitas" object everything runs fine. Is it possible to "nest" as this?
UPDATE:
Ajax Part:
$.ajax({
type: 'post',
url: 'cxxx.php',
data: { asn: asn },
success: function(p){
p = JSON.parse(p);
jusante=JSON.parse(p.jusante);
montante=JSON.parse(p.montante);
vazao=JSON.parse(p.vazao);
minima=JSON.parse(p.minima);
fator=JSON.parse(p.fator);
visitas=JSON.parse(p.visitas)
and PHP part:
$v="[";
while(odbc_fetch_row($res)){
$datavisita = odbc_result($res, "DATA_VISITA");
$descricaovisita = odbc_result($res, "DESCRICAO_VISITA");
$login = odbc_result($res, "LOGIN");
$descricaomotivo = odbc_result($res, "DESCRICAO_MOTIVO");
$id_motivo=odbc_result($res, "ID_MOTIVO");
$datavisita=date("U", strtotime($datavisita))*1000;
$descricaovisita=preg_replace("/\r|\n/", "", $descricaovisita);
$v.="{x:$datavisita,text:'$descricaovisita',title:'$id_motivo'}, ";
}
$v=rtrim($v,", ")."]";
echo "{\"asn\": \"$asn\", \"description\": \"$description\", \"jusante\": \"$o\", \"montante\": \"$m\", \"vazao\": \"$f\", \"minima\": \"$mn\", \"fator\": \"$fp\", \"visitas\": \"$v\" }";
the Json you are using is valid, I checked it on JSONLint, so your problem might be with serialization, just make sure your "visitas" object is serialized correctly because the problem might be happening because it's the only member with an object value inside
Remove the quotes around the visitas array:
var json = JSON.parse('{"asn": "167","jte": "[[1381547700000,0.0], [1381548600000,0.0]]", "visitas": [{"x": "1380596400000", "text":"HELLOWORLD.","title":"X"}]}');
While the outermost JSON object looks fine, there might be a problem with the nested one!
If you are trying to parse the nested JSON element "visitas" you might have a problem in the fact that your property names (e.g. x, text and title) are not enclosed in quotation marks ("). This is of course a bit tricky since you are trying to include the visitas element as a string.
A solution might be to include the visitas element as a proper JSON element instead.
You need to escape the single quotes. I imagine you are surrounding the above in single quotes when you pass it to JSON.parse.
The below works.
JSON.parse('{"asn":"167", "jte":"[[1381547700000,0.0], [1381548600000,0.0]]", "visitas":"[{x:1380596400000,text:\'HELLO WORLD.\',title:\'X\'}]"}');
Note the slashes before the single quotes inside the string.
I would do the following:
var jsondata = {
"asn": "167",
"jte": "[[1381547700000,0.0], [1381548600000,0.0]]",
"visitas": "[{x:1380596400000,text:'HELLO WORLD.',title:'X'}]"
};
jsondata = JSON.stringify(jsondata);
then send it to php
var postdata = { data : jsondata};
var url = "<?php echo base_url(); ?>"+"test";
$.post(url, postdata, function(result){
console.log(result);
});
sice your php result is echoed the wrong way you should fix that first. Create arrays so that you can easily use the JSON_ENCODE function like so:
$array = array(
"asn" => "test_asn",
"description" => "description_test",
"jusante" => "jusante_test",
"montante" => "montante_test",
"vazao" => "vazao_test",
"minima" => "minima_test",
"fator" => "fator_test",
"visitas" => "visitas_test"
);
$json = json_encode($array);
echo $json;

json_encode with multidimensional array returning string "array" instead of data

I am passing a multidimensional array back to a .php file using json, jquery, and ajax. My goal is essentially to fill a drop down box (id=project) with multiple entries. Here's some code snippets:
$("#turninId").change(function() {
var user_id = $("#turninId").val();
$.ajax ( {
url:"send_input.php",
type: "POST",
dataType: "json",
data:{id_selection: user_id},
success:function(response) {
for (var i=0; i<response.proj.length; i++) {
$("#exp").html(response.proj[i]);
$("#project").html(response.proj[i]); } });
});
In send_input.php (backend), I query a db, and send the information to an array. Then I use json_encode.
$query="SELECT project FROM main";
$results = $db->query($query);
while ($row_id = $results->fetchArray()) {
$proj_option[] = "<option value=\"".$row_id['project']."\">".$row_id['project']."</option>\n";
$pselected=$row_id['project'];
}
$output = array( "proj" => "$proj_option");
echo json_encode($output);
My problem is that this is RETURNING THE STRING "Array".
For example, if I do: response.proj[0], I get "A" returned.
What gives? I've seen a few people with questions about this error, but no definite solution. Any help?
This is because you are casting $proj_option to a string by enclosing it in quotes. Just remove the quotes and you will get the array.

Ajax JSON exception Unexpected token [

hi i have a page contains a link , when user click the link i want to go to database and retrieve two arrays , but when i alert those two arrays i got this exception
Unexpected token [
this is my js code
function acNewConcpet(element){
var parent = element.parentNode;
parent.removeChild(element);
var concpetSelect = document.createElement('select');
var relationSelect = document.createElement('select');
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
var data = JSON.parse(xmlhttp.responseText);
alert(data);
}
}
xmlhttp.open("GET","http://localhost/Mar7ba/Ontology/getRelatedConceptsAndRelations/"+"concept"+"/TRUE",true);
xmlhttp.send();
}
and this is my php code
public function getRelatedConceptsAndRelations($concpetName, $Ajax) {
if ($Ajax) {
$concepts = array('c1', 'c2');
$relations = array('r1','r2');
echo json_encode($concepts);
echo json_encode($relations);
}
return;
}
why is this exception ? and how can i solve it ? and how can i receive those two arrays in my js ?
this is full code code
JSON.parse can only parse a single JSON literal.
You should combine the two arrays into a single object with two properties.
You are returning malformed JSON. From what I understand from your code, it prints out this JSON:
['c1','c2']['r1,r2']
You cant have 2 arrays like this. You must print it like:
[['c1','c2'],['r1','r2']]
Sorry for my rusty PHP, but you must have something like:
$json = array(
array('c1','c2'),
array('r1','r2')
);
echo json_encode($json);
Since you are using jQuery, why not use $.getJSON()?
$.getJSON(url,function(returnData){
//returnData is the parsed JSON
});
When you response a JSON, it needs to be one JSON, but you are sending two seperate arrays.
Merge those two JSONs into one.
Update:
Do it like this:
public function getRelatedConceptsAndRelations($concpetName, $Ajax) {
if ($Ajax) {
$concepts = array('c1', 'c2');
$relations = array('r1','r2');
echo json_encode(array($concepts, $relations));
}
return;
}

Categories

Resources