.length counts characters, not the array length - javascript

I want to count the items of an array returned by json. When I use response.length, it counts all the characters in the array(I guess so) while what I want it to do is to count how many items are there in the array. Same method works in another pages, just not with this one.
This is the php code:
...$response[] = array("id" => $row['appid'],
"hour" => $row['hour'],
"tname" => $tname,
"tsurname" => $tsurname,
"cname" => $cname,
"csurname" => $csurname,
"cgsm" => $cgsm,
"cemail" => $cemail,
"cdept" => $cdept,
"cdeg" => $cdeg,
"purpose" => $purpose,
"clientnotshown" => $row['clientnotshown']);
};
if(isset($response)){
echo json_encode($response);
} else {
$response = array("val" => 0);
echo json_encode($response);
};
Javascript code:
function updateTable() {
var getData = {
date: $("#displaydate").val(),
operation:"getData"
}
$.post( "printoperations.php", getData).done(function( response ) {
if (response.val != 0){
alert("so far so good")
var arrayLength = response.length
alert(response)
alert(arrayLength)}
};
Here is a picture of what I get. I want to get the count of items, which in this case is 2.

Whatever you send back from PHP is always a string.
jQuery will however parse that string for you automagically, if you either send the correct headers, or tell it that it's JSON in the settings
$.post("printoperations.php", getData, function(response) {
if (response.val != 0) {
console.log("so far so good")
var arrayLength = response.length
console.log(response)
console.log(arrayLength)
}
}, 'json'); // <- here
And use the console for debugging

You need to parse the response var response = JSON.parse(response) and then response.length will return the desired result.

var getData = {
date: $("#displaydate").val(),
operation:"getData"
}
$.post( "printoperations.php", getData).done(function( response ) {
if (response.val != 0){
alert("so far so good")
var responseArray = JSON.parse(response)
alert(responseArray)
alert(responseArray.length)}
};

Seems you are trying to find length of string. Instead, try to alert(typeof response), If it gives string, then before doing anything parse it to JSON with JSON.parse(response) and then try.

JSON.parse(response)That did the trick. Thanks for all answers!

You should put this
header('Content-Type: application/json');
in your server side php query.

Related

How to get value from Encode json data on php pages

I try to take object from my controller, when I console.log(response) it show the value correctly which is in
[
{
"itemValue":100,
"itemUnit":"2"
}
]
unfortunately I try to use the object like response.itemValue when I console it show undefined. I try var object = response. during the console it show the same value. Please I want to use the response data.
if(itemID){
$.ajax({
type:'POST',
url:'?syspath=ajax&controller=ajax&action=getActItemDose',
data: { 'itemId': itemID, 'itemType': itemType },
success:function(response){
// var obj = jQuery.parseJSON(data);
console.log(response);
var object = response;
var value = object.itemValue;
var unit = object.itemUnit;
console.log(object);
console.log(value);
}
});
}
This is controller where I encode the object into Json
$row = $getProcess->fetch();
$object[] = array(
'itemValue' => $row['each_dose'],
'itemUnit' => $row['unit_dose']
);
echo json_encode($object);
I recommend using the jQuery library. For parsing JSON, simply do
var obj = JSON.parse(data);
// Accessing individual value from JS object
alert(obj.itemValue);
alert(obj.itemUnit);
It worked, by changing this few item
$object[] = array();
into
$object = array();
and JSON.parse(data)
var object = JSON.parse(data);
value = object.itemValue;
unit = object.itemUnit;
Your response is an array. So you need to access it like
response[0].itemValue
or you can loop through the array
response.forEach(element => {
console.log(element.itemValue);
});
Below is the example
const response = JSON.parse(`[
{
"itemValue":100,
"itemUnit":"2"
}
]
`);
response.forEach(element => {
console.log(element.itemValue);
});

jquery ajax refreshes page on failed callback

so i'm just not sure where i'm going wrong on this issue. it's one of those things everything was working fine and i made an adjustment, then i fell asleep and can't remember what i did. so my issue is that this ajax call fails:
var url = 'lib/php/addToCart.php';
var sent = $.post(url, data, null, 'json');
sent.done(function (data) {
$('.badge').html(Object.keys(data).length);
console.log('item added to cart');
alert("Added To Your Cart. Please Continue Shopping");
});
sent.fail(function (data, b, c) {
console.log("failed adding item: " + c);
var propValue;
for(var propName in b) {
propValue = b[propName];
console.log(propName,propValue);
}
});
the only errors i can get from the fail is "error" and when i do the jqXHR error i get a function in response.
here is my php file that is being called:
session_start();
$itemNum = $_POST['upc'];
$price = $_POST['price'];
$title = $_POST['title'];
$qty = 1;
$cartData = $conn->prepare("SELECT available FROM yardSale.dvdTbl WHERE upc = ?");
$cartData->bind_param("s", $itemNum);
$cartData->execute();
$cartData->store_result();
$cartData->bind_result($available);
$cartData->fetch();
$linePrice = $price * $qty;
$cartName = $title;
$_SESSION['cart'][$cartName] = array(
"cartName" => $cartName,
"itemNum" => $itemNum,
"title" => $title,
"itemPrice" => $price,
"linePrice" => $linePrice,
"qty" => $qty,
"available" => $available
);
echo json_encode($_SESSION['cart']);
and then if you need it i have an event handler to go to the function with the ajax call:
event.stopImmediatePropagation();
var upcNum = $(this).attr('id');
var formID = 'info:' + upcNum;
console.log(upcNum);
var formData = $(this).serialize();
console.log(formData);
addItem(formData);
i'm sure this is another one of those really stupid things i'm over looking... but i can't figure out where the error would be coming from, or why the page is refreshing.
in fire bug the file just shows up red and only has the request headers, no response headers. the real kicker for me is that the php file actually processes the information like it's supposed to and the json that should be returned would be valid json.
and please don't laugh at my code... if you want to help i take criticism very well; but please don't patronize me.
Just needed event.preventDefault()... thanks Code Spirit
I think the error is in this part of code:
for(var propName in b) {
propValue = b[propName];
console.log(propName,propValue);
}
The variable propName is not the index but is the value, so you must do something like this:
for(var propIndex in Object.keys(b)) {
propValue = b[propIndex];
console.log(propIndex,propValue);
}

Retrieving a JSON.parse() string from a server

I will start by saying that I am learning how to program in jquery/javascript, and am running into an issue using JSON.parse(). I understand the format, and why people use it... but have not been able to get it to work in any of my code projects.
I have read in books/online on here in how to use it, but I think I read too much on it. I am now confused and second guessing what I know about it.
With that said, my jquery/javascript class I am taking is asking me to use it for an assignment, through AJAX using MAMP/localhost as the server.
The two codes below are for the section that I need to fill in the //TODO information. One is javascript (client-side), the other is php (server-side). I think that I've set the other //TODO information correctly, but I keep getting a token error for the JSON part.
I looked on here for a solution, but again, I think I've confused myself badly and need help. Appreciate any feedback, insight, or information.
-Javascript-
var calculateMpg = function () {
// These lines are commented out since the server will perform these checks
// if (!checkNumber("miles") || !checkNumber("gallons")) {
// return;
// }
var miles = $("#miles").val();
var gallons = $("#gallons").val();
console.log("ajax request issued.");
var result;
$.ajax({
url: "service.php?action=calculateMPG&miles="+miles+"&gallons="+gallons,
cache: false,
dataType: "text",
success: function(msg) {
console.log("ajax response received.");
// TODO: parse the JSON string returned from the server (see JSON.parse())
JSON.parse("result");
if (result.status === 'success') {
// TODO: get the mpg value returned from the server and display it to the user.
$("#mpg").val($_GET("result"));
console.log("JSON Working!");
}
else {
// TODO: get the name of the variable with the error. Hint: look at the 'fail' result from service.php
$_GET[fail(id)];
// TODO: report the error to the user using invalidNumber() function.
alert("{status: 'failure', variable: <variable name>}");
}
}
});
};
$(document).ready( function () {
$("#miles").blur(function () {
checkNumber("miles");
});
$("#gallons").blur(function() {
checkNumber("gallons");
});
$("#calculate").click(calculateMpg);
$("#miles").focus();
});
-PHP-
<?php
if ($_GET) {
if ($_GET['action'] == 'calculateMPG') {
$miles = htmlspecialchars($_GET['miles']);
$gallons = htmlspecialchars($_GET['gallons']);
// validate miles
if (strlen($miles) == 0) {
fail("miles");
}
$miles_chars = str_split($miles);
for ($i=0; $i< count($miles_chars); $i++) {
if ($miles_chars[$i] < "0" || $miles_chars[$i] > "9") {
//error_log("miles_chars check failed at: " + $i);
fail("miles");
}
}
// validate gallons
if (strlen($gallons) == 0) {
fail("gallons");
}
$gallons_chars = str_split($gallons);
for ($i=0; $i< count($gallons_chars); $i++) {
if ($gallons_chars[$i] < "0" || $gallons_chars[$i] > "9") {
fail("gallons");
}
}
// validate $miles and $gallons calling $fail along the way
$result = $miles/$gallons;
if ($result) {
success($result);
} else {
fail("mpg");
}
exit ;
}
}
function fail($variable) {
die(json_encode(array('status' => 'fail', 'variable' => $variable)));
}
function success($message) {
die(json_encode(array('status' => 'success', 'message' => $message)));
}
Edited Additional 1
I have made changes to the JSON information in regard to 'var result' (thanks to several of the responses here). I'm starting to understand JSON a bit better.
Another question I have (now) is how to isolate a part of the JSON message from the whole being transmitted?
A piece of the 'JSON.parse(msg)' returned DOES include the answer to the equation miles/gallons, but I don't know how to... extract it from the JSON.
The solution to the equation miles/gallons appears in the 'msg' output.
Thanks.
Edited Additional 2
This question has been solved! While perusing around stackoverflow for a solution to the question in my previous edited section, I found my answer here: JSON response parsing in Javascript to get key/value pair.
The answer is this: under the //TODO section asking for the mpg value, I put the following code - $("#mpg").val(result.message); - which says that in the JSON section of the variable result, take the part of the JSON marked 'message', the value being the equation solution.
Thank you to all who responded with their solutions to my problem. I appreciate the fast responses, the great suggestions, and the information in understanding JSON.
-ECP03
JSON.parse() requires that you send it a valid JSON string.
"result" is not a valid JSON string. In your success function you have defined a parameter msg - what does this contain? Try console.log(msg) at the beginning of your success function and look at the console output.
You have two options:
Option 1: -- Parse the string returned.
Change JSON.parse("result"); to:
var result = JSON.parse( msg );
Option 2: -- Request JSON instead of plain text - no need to parse
Use $.getJSON() which is shorthand for:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
Instead of parsing the JSON yourself, jQuery already provides you with a convenient function that will parse JSON:
var path = "service.php?action=calculateMPG&miles="+miles+"&gallons="+gallons;
$.getJSON(path, function (data) {
if (data.status == 'success') {
console.log('Success! Message:', data.message);
} else {
console.log('Failed :( Variable:', data.variable);
}
});
For your original code, what you would need to do is call JSON.parse(msg) in your success callback, which would return a JavaScript object with the values you sent from your PHP script. By specifying dataType: 'json' in the $.ajax call, jQuery does this for you. The $.getJSON method does this and some other things for you.
You need to use the result returned by the success function:
var result = JSON.parse(msg);
Then, you could do stuff like result.status.
When you put JSON.parse("result") you're saying "parse the string 'result'," which doesn't make any sense. However, if you say JSON.parse(msg) you're saying "Parse the variable that was returned from the ajax action," which makes sense.
JSON.parse() is used to convert your json data to object, then you can manipulate it easly.JSON.parse(msg); instead of JSON.parse("result").
For example:
var json = '{"value1": "img", "value2":"img2"}'
var obj = JSON.parse(json);
for ( k in obj ) {
console.log(obj[k])
}
This is totally wrong: JSON.parse("result");. .parse() expects a JSON string, e.g. the string that came back from you ajax request. You're not providing that string. you're providing the word result, which is NOT valid JSON.
JSON is essentially the right-hand side of an assignment expression.e.g.
var foo = 'bar';
^^^^^---this is json
var baz = 42;
^^---also json
var qux = ['a', 'b', 'c'];
^^^^^^^^^^^^^^^---even more json
var x = 1+2;
^^^---**NOT** json... it's an expression.
What you're doing is basically:
var x = parse;
^^^^^^---unknown/undefined variable: not JSON, it's an expression

Delete multiple objects Amazon s3 PHP SDK

I'm having issues deleting multiple objects at once..
Using this library-
https://github.com/aws/aws-sdk-php-laravel
I have no issues with anything else using the library (putting, getting, deleting single objects, etc.)
try {
$s3 = AWS::get('s3');
$s3->deleteObjects(array(
'Bucket' => $bucket,
'Objects' => $json['attachmentArray']
));
return "Success deleting files.";
} catch (S3Exception $e) {
return "There was an error.\n";
}
deleteObjects Amazon Docs- http://docs.aws.amazon.com/AmazonS3/latest/dev/DeletingMultipleObjectsUsingPHPSDK.html
I get returned "Success deleting files.";, but the files are not being deleted.
My bucket name is correct, and the $json['attachmentArray'] is in the right format according to the docs (again, I have no issues with other areas like put, get, delete)
Where am I messing up?
Trying to give more info:
I am POSTing info from an Angular function to Laravel endpoint.
Here is the Angular function (Firebase URL hidden):
$scope.deleteFile = function() {
var r=confirm("Are you sure you want to delete this task & of it's all attachments?");
if (r==true)
{
var attachmentArray = [];
var atttachData = new Firebase('https://*.firebaseio.com/attachments');
atttachData.on('value', function(dataSnapshot) {
dataSnapshot.forEach(function(childSnapshot) {
var key = childSnapshot.val().key;
// attachmentArray.push(key); I tried this
attachmentArray.push({Key:key});
});
});
method: "POST",
url: '/delete_task',
data: {attachmentArray:attachmentArray},
headers: {'Content-Type': 'application/json'},
}).success(function(data){
console.log(data);
});
}
}
And here is my Laravel controller that I am trying to make deleteObjects (with updated code from #Kevin Florida:
public function delete_task() {
$request = Request::instance();
$task = $request->getContent();
$json = json_decode($task, TRUE);
$bucket ='bucketname/team1';
// return $json['attachmentArray'];
$s3 = AWS::get('s3');
if(!$s3->deleteObjects(array(
'Bucket' => $bucket,
'Objects' => $json['attachmentArray']
))) {
return "error";
} else {
return "success";
}
}
Now this returns a 500 server error.. I think I'm formatting $json['attachmentArray']; incorrectly? I'm not sure.
Angular function
$scope.deleteFile = function() {
var r=confirm("Are you sure you want to delete this task & of it's all attachments?");
if (r==true)
{
var attachmentArray = [];
var atttachData = new Firebase('https://***/attachments');
atttachData.on('value', function(dataSnapshot) {
dataSnapshot.forEach(function(childSnapshot) {
var url = childSnapshot.val().url;
var name = childSnapshot.val().name;
var id = childSnapshot.val().id;
var key = childSnapshot.val().key;
attachmentArray.push(key);
});
});
$http({
method: "POST",
url: '/delete_task',
data: {team:$scope.team,attachmentArray:attachmentArray,lastSegment:lastSegment},
headers: {'Content-Type': 'application/json'},
}).success(function(data){
console.log(data);
});
}
}
Laravel controller
public function delete_task() {
$s3 = AWS::get('s3');
$task = Input::all();
$bucket ='teamite/team'.$task['team'];
//make the array for Objects on this side
foreach ($task['attachmentArray'] as $value) {
$array[] = array('Key' => $value);
}
// return $task['attachmentArray'][0];
$result = $s3->deleteObjects(array(
'Bucket' => 'teamite/team1',
'Objects' => $array
));
return $result;
}
And I log this response in the console from Amazon:
=====================
Debug output of model
=====================
Model data
-----------
This data can be retrieved from the model object using the get() method of the model (e.g. $model->get($key)) or accessing the model like an associative array (e.g. $model['key']).
[Deleted] => Array
(
[0] => Array
(
[Key] => 4700pzgds4i_ad.jpg
)
[1] => Array
(
[Key] => xxvu29ms4i_ad.jpg
)
)
[RequestId] => 477F0DA04101D82E
So it seems to be working correctly now. But the objects are not being deleted?
What else am I doing wrong?
It actually looks like you are not referencing the files (S3 objects) correctly. The formatting of the request is fine, but the bucket name and keys may be wrong.
Looking at:
$bucket = 'teamite/team'.$task['team'];
Is your bucket called "teamite/team1" or just "teamite"? Keep in mind that S3 has a flat structure. There are no "subbuckets". If you have things laid out in a nested file structure, then the paths, or pseudo-folders, need to be included as part of the key.
For example, in this imaginary URL to an object in S3: http://s3.amazonaws.com/all-of-my-things/photos/2013/12/photo0005.jpg
The bucket is all-of-my-things, and the key is photos/2013/12/photo0005.jpg.
The deleteObjects() call you are making is returning successfully because of the idempotent nature of S3 operations. If you delete an object multiple times, it will return successfully every time. What you are seeing here is that you are deleting objects using the wrong keys. Those keys don't exist, and therefore are already deleted.
Hopefully this helps. Don't be afraid to reach out on the module's issue tracker or directly on the SDK's issue tracker for problems like this when you are working directly with the SDK objects.
To delete s3 file use it
It work for me -
$s3 = AWS::get('s3');
$s3->deleteMatchingObjects('Your Bucket Name', 'File name to delete');
For testing try:
if(!$s3->deleteObjects(array(
'Bucket' => $bucket,
'Objects' => $json['attachmentArray']
))) {
return "error";
} else {
return "success";
}
catch will only return "There was an error" if an exception occurs, not if the deleteObjects() method returns false

JSON array in Node.js

I have been trying to figure this out for the past week and everything that i try just doesn't seem to work.
I have to create a web service on my local box that responds to requests. The client (that i did not write) will ask my service one question at a time, to which my server should respond with an appropriate answer.
So the last thing i have to do is:
When a POST request is made at location '/sort' with parameter 'theArray', sort the array removing all non-string values and return the resulting value as JSON.
theArray parameter will be a stringified JSON Array
From going through trail and error i have found out that the parameters supplied is:
{"theArray":"[[],\"d\",\"B\",{},\"b\",12,\"A\",\"c\"]"}
I have tried many different thing to try to get this to work. But the closest thing i can get is it only returning the same thing or nothing at all. This is the code that i am using to get those results:
case '/sort':
if (req.method == 'POST') {
res.writeHead(200,{
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
});
var fullArr = "";
req.on('data', function(chunk) {
fullArr += chunk;
});
req.on('end', function() {
var query = qs.parse(fullArr);
var strin = qs.stringify(query.theArray)
var jArr = JSON.parse(fullArr);
console.log(jArr); // Returns undefided:1
var par = query.theArray;
console.log(par); // returns [[],"d","B",{},"b",12,"A","c"]
function censor(key) {
if (typeof key == "string") {
return key;
}
return undefined;
}
var jsonString = JSON.stringify(par, censor);
console.log(jsonString); // returns ""
});
res.end();
};
break;
Just to clarify what I need it to return is ["d","B","b","A","c"]
So if someone can please help me with this and if possible responded with some written code that is kinda set up in a way that would already work with the way i have my code set up that would be great! Thanks
Edit: Try this:
var query = {"theArray":"[[],\"d\",\"B\",{},\"b\",12,\"A\",\"c\"]"};
var par = JSON.parse(query.theArray);
var stringArray = [];
for ( var i = 0; i < par.length; i++ ) {
if ( typeof par[i] == "string" ) {
stringArray.push(par[i]);
}
}
var jsonString = JSON.stringify( stringArray );
console.log(jsonString);
P.S. I didnt't pay attention. Your array was actually a string. Andrey, thanks for the tip.
The replacer parameter of JSON.stringify doesn't work quite like you're using it; check out the documentation on MDN.
You could use Array.prototype.filter to filter out the elements you don't want:
var arr = [[],"d","B",{},"b",12,"A","c"];
arr = arr.filter(function(v) { return typeof v == 'string'; });
arr // => ["d", "B", "b", "A", "c"]
edit: one-liner (try it in repl!)
JSON.stringify(JSON.parse(require('querystring').parse('theArray=%5B%5B%5D%2C"d"%2C"B"%2C%7B%7D%2C"b"%2C12%2C"A"%2C"c"%5D').theArray).filter(function(el) {return typeof(el) == 'string'}));
code to paste to your server:
case '/sort':
if (req.method == 'POST') {
buff = '';
req.on('data', function(chunk) { buff += chunk.toString() });
res.on('end', function() {
var inputJsonAsString = qs.parse(fullArr).theArray;
// fullArr is x-www-form-urlencoded string and NOT a valid json (thus undefined returned from JSON.parse)
var inputJson = JSON.parse(inputJsonAsString);
var stringsArr = inputJson.filter(function(el) {return typeof(el) == 'string'});
res.writeHead(200,{
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
});
res.end(JSON.stringify(stringsArr));
};
break;

Categories