I don t know why data formated as json using JSON.parse function return as Array type when I want to check the new converted type.
First I made ajax request to go and fetch data from a database as illustrated below
$.ajax({
url:'processBet.php',
data:'',
success:function(data){
//below I check the return data type
console.log( Object.getPrototypeOf(JSON.parse(data)));
//the return type is array.....why?
console.log((JSON.parse(data)); // to see the data
}
});
Obviously in the file that fetch data in the database will put data in Array.So before sending it I converted it in JSON using a php function json_encode as illustrated below
$ql = "SELECT * from tempdata" ;
$result=$pdo->query($ql);
$result->setFetchMode(PDO::FETCH_ASSOC);
while($data = $result->fetch()){
$arrays[]=$data;
}
//Now I convert in json before sending
$json =json_encode($arrays);
echo $json; // the return data supposed to be json type
Below is the sample of the data return after succeessfull ajax request
So Iwould like to know why the return type is still array and not JSON since a new conversion has been made when the ajax request succeed
The reason is because how you are setting up your array before encoding it.
$arrays[] = $data;
PHP will set it as an object if the depth of the elements go beyond just an array of arrays.
Example:
If you create a simple 2d array like this one:
$p = [
'name' => 'jack',
'job' => 'ceo',
'age' => 'old'
]; // {"name":"jack","job":"ceo","age":"old"}
You will have an Object in your JS code; That's because of the way PHP handles it. However, look at this example as an alternative: This will return an array of objects:
$p = [[
'name' => 'jack',
'job' => 'ceo',
'age' => 'old'
],[
'name' => 'sam',
'job' => 'cool',
'age' => 'decent'
]];
echo json_encode($p); //[{"name":"jack","job":"ceo","age":"old"},{"name":"sam","job":"cool","age":"decent"}]
It's all about that key placement. If you have a key => pair array it will become an Object no matter what. Look at another example of a simple JS array:
print_r(json_encode([
'burger',
'pizza'
])); // ["burger","pizza"]
But if you add just one key=>pair to your array it will become an json object:
print_r(json_encode([
'burger',
'pizza',
'people' => [
'jack' ,
'sam',
'pete'
]
])); // {"0":"burger","1":"pizza","people":["jack","sam","pete"]}
Just for educational purpose if you throw it inside another 1d array you will get an array objects:
print_r(json_encode([[
'burger',
'pizza',
'people' => [
'jack' ,
'sam',
'pete'
]
]])); // [{"0":"burger","1":"pizza","people":["jack","sam","pete"]}]
Explanation:
When dealing with an array, it will strictly handle it's key from 0 to however many items are in the array; so an array in json_encode terms is anything with a simple 1d interface:
Which in PHP & JavaScript would look like this:
PHP
print_r([
'burger',
'pizza'
]); // Array ( [0] => burger [1] => pizza )
Javascript
console.log([
'burger',
'pizza'
]); // Array [ "burger", "pizza" ]
When adding the key to your array and making it into a 2d or more complex json_encode will convert it to a JavaScript Object; as we saw in the first example:
Related
I wanting to replicate this array structure in Javascript, but I cannot figure out how to do it, in my php I have the following,
$myArray = array();
$myArray['location1'] = array('name' => 'Texas', 'person' => 'Jim');
$myArray['location2'] = array('name' => 'California', 'person' => 'Jeff');
This would leave me a structure that looks like,
myArray = array(
'location1' = array('name' => 'Texas', 'person' => 'Jim')
'location2' = array('name' => 'California', 'person' => 'Jeff')
)
What I wanting in javascript is an array that holds other arrays and the sub arrays are keyed is this possible?
As stated by Steven, Javascript Arrays are not associative. However, you can parse an Associative PHP Array as a JSON Object which will led to the same structure when passing from or to Client Side.
P.E In PHP you'd have
$myArray = [
"tag"=>"property",
"properties"=>[
"color"=>"blue",
"name"=>"A Name"
]
];
Then, you return this array as JSON
return json_encode($myArray);
And when you receive it on Javascript you do a JSON Parse with the response
function getMyObject()
{
// Code for retrieving the JSON From Server
//End of Code for JSON Retrieval
const myObject = JSON.parse(response);
}
This will led to an structure such as this in Javascript
console.log(myObject)
>>>>
{
tag:"property",
properties:{
color:"blue",
name:"A Name"
}
}
Which you can access with the object.key notation or object[key] in Javascript.
Most of frameworks do this in a transparent way. For example, if you're using Laravel when you return the Array as a response in an API route, it will automatically parse it as a JSON. And then, in a framework such as Angular, the HttpClient will automatically parse the JSON response as a JavaScript object.
Then, in the opposite direction, if you send a object to an Endpoint. It will automatically be converted to a JSON body in the request and parsed by the backend framework.
I am receiving a json response from an API call. I need to store its keys, and create an array of an object. I am intending to this array of an object is created dynamically no matter the keys of the response.
I've already got the keys like this:
const json_getAllKeys = data => {
const keys = data.reduce((keys, obj) => (
keys.concat(Object.keys(obj).filter(key => (
keys.indexOf(key) === -1))
)
), [])
return keys
}
That returned an array (using a sample json):
['name','username', 'email']
But I am trying to use that array to create an array of object that looks like this one
[
{
name: "name",
username: "username",
email: "Email",
}
];
I've been trying mapping the array, but got multiple objects because of the loop, and I need a single one to make it work.
keys.map(i=>({i:i}))
[
{ i: 'id' },
{ i: 'name' },
{ i: 'username' },
{ i: 'email' }
]
Any hint would be useful!
Thanks in advance :D
What you're looking for is Object.fromEntries, which is ECMA2019, I believe, so available in Node >=14 and will be provided as a polyfill if you employ babel.
I can't quite discern what your reduce should produce, but given the sample input, I would write
const input = ['name','username', 'email'];
const result = Object.fromEntries(input.map(name => ([name, name])));
// result == { name: 'name', username: 'username', email: 'email' }
You're definitely on the right track. One thing to remember is the map function will return the SAME number of output as input. So in your example, an array of 3 returns an array of 3 items.
For this reason, map alone is not going to give you what you want. You may be able to map => reduce it. However, here is a way using forEach instead. This isn't a strictly functional programming style solution, but is pretty straight forward and depending on use case, probably good enough.
let keys = ['name','username', 'email'] //you have this array
const obj = {}; // empty object to hold result
keys.forEach(i => {
obj[i] = i; // set the object as you want
})
console.log(obj); // log out the mutated object
// { name: 'name', username: 'username', email: 'email' }
I'm querying a database in Javascript where I get back a Map object. The problem is that the key of some entry in the map is an object, an EnumValue to be precise.
I can't seem to find a way to directly retrieve this kind of entries. The only that comes to my mind is to iterate on every single key of the map and check if it's an object.
So, if I console.log the output I get from the query, it looks like this:
Map {
EnumValue { typeName: 'T', elementName: 'label' } => 'user',
'gender' => [ 'f' ],
'identityid' => [ '2349fd9f' ],
'name' => [ 'Erika' ],
'email' => [ 'test1#test.com' ],
EnumValue { typeName: 'T', elementName: 'id' } => 4136,
'lastname' => [ 'Delgato' ]
}
I've naively already tried to get the entry using something like this:
const enumId = { typeName: 'T', elementName: 'label' };
map.get(enumId)
But of course it returns undefined.
Any ideas?
So, for saving the time to anyone else that incours in this problem I'll write the solution here.
This problem is specific to values retrieval in a Janusgraph database, using the gremlin javascript client (version 3.4.2 used here).
When appending valueMap(true) to a traversal, the result is the one in the question I posted.
Going through the gremlin library, I found out that inside the object t from gremlin.process.t this EnumValues can be found:
id
key
label
value
Then using the id or label it is possible to directly retrieve the values with those nasty keys.
An example:
// Let's say we already have the Map from the question stored in a map variable
// To get the id of the result you can do the following
const t = gremlin.process.t;
const id = map.get(t.id);
console.log(id) // 4136
Map in javascript work by reference. It does not make a deep comparison, only check if the pointer is the same.
This will not work:
var x = new Map()
x.set({},'lala')
x.get({}) // undefined
But this will work:
var x = new Map()
var player = {name: 'ben'}
x.set(player, 50)
x.get(player) // 50
I have the following javascript that sends data to a PHP function:
<script>
var mydata = {
id:123,
name: 'mike',
orders: []
};
$.ajax({
type: 'POST',
url: 'test.php',
data: {save_data:mydata},
success: function(data) {
alert('php received: ' + data);
}
});
</script>
and my test.php file contains the following code:
<?php
if (isset($_POST['save_data'])) {
$json = json_encode($_POST['save_data']);
echo $json; // just to check what has been received
exit();
}
?>
What I expect to received from PHP is:
{"id":"123","name":"mike","orders":"[]"}
What I got back is {"id":"123","name":"mike"}
Notice that orders array has been eliminated from the output. No place holder for it. I tried adding some dummy elements in the array, and that worked fine, and I received the array back with the elements.
I need PHP to receive the json object as is, even if it contains empty arrays.
How can I do that?
The JSON object is created inside PHP. Before then you just have form data.
jQuery will encode form data in a PHP-friendly style.
If you give it:
data: { foo: [1, 2, 3] }
It will convert that to:
foo[]=1&foo[]=2&foo[]=3
(although it will percent encode the [])
You get a key=value pair for each value.
If you have an empty array then you don't have any values, so you don't get any key=value pairs.
There is no way to encode "an empty array" using PHP's extensions to the form url encoding syntax.
You have two basic options:
Tell PHP about what data structure you want to create in advance and have it fill in the empty arrays.
Generate the JSON on the client
It is not error of PHP. It cause by Jquery will igrone empty array when send it to server. So you have to parse array in 'orders' key to string JSON before send
var mydata = {
id:123,
name: 'mike',
orders: []
};
Change to
var mydata = {
id:123,
name: 'mike',
orders: JSON.stringify([])
};
Basically I got my app up an running but I'm stuck with a problem: if I pass an object that contains an empty array to be saved, the array is not saved into the db. I'm not sure this is a problem in js or the mongo driver, but in order to save the empty array I need to pass the array like so: products: [''].
This is the structure of my mongo document:
_id: ObjectId(...),
name: 'String',
subcategories: [
{
subcategory: 'string',
products: [
{
name: 'string'
price: integer
}
]
}
]
So in my front-end I'm grabbing the whole document through an ajax call pushing a new object into the subcategories array. The new object looks like this:
{subcategory:'string', products:['']}
And this works okay until I need to insert a new object inside the array: Because I've grabbed the whole object, pushed the new object to the array, the previous one looks like this:
{subcategory: 'string'}
Having lost the mention to products:[] array in the process.
How can I get around this? I need to be able to have empty arrays in my object.
EDIT
What I did on front end: Got the whole object with $.get which returned:
var obj =
_id: ObjectId(...),
name: 'String',
subcategories: [
{
subcategory: 'Subcategory1',
products: [
{
name: 'string'
price: integer
}
]
}
];
Then on the front end I've pushed the new object category inside the subcategories array:
data.subcategories.push({subcategory: 'Subcategory2', products: ['']})
Where subcat was a string with the category name. On my db I could see that I've successfully added the object:
var obj =
_id: ObjectId(...),
name: 'String',
subcategories: [
{
subcategory: 'Subcategory1',
products: [
{
name: 'string'
price: integer
}
]
},
{
subcategory: 'Subcategory2'
products: []
}
];
The problem was when I wanted to add another subcategory, the previous one return empty:
var obj =
_id: ObjectId(...),
name: 'String',
subcategories: [
{
subcategory: 'Subcategory1',
products: [
{
name: 'string'
price: integer
}
]
},
{
subcategory: 'Subcategory2'
},
{
subcategory: 'Subcategory3'
products: []
},
];
Because at some point the empty array was removed from the object. Like I said, I did fix this in the front end, so the error jade was throwing has been addressed, but I still find odd that the products: [] was being removed from the document.
I'm new to MongoDb and node, not to mention that I'm also new with JS, so it might well be a feature that I'm unaware of.
When passing empty arrays to Mongo they are interpreted as empty documents, {}. Zend Json encoder will interpret them as empty arrays []. I understand that it's not possible to tell which one is correct.
Incase of empty arrays try posting as
Array[null];
instead of Array[];
This will be working fine
When passing empty arrays to Mongo they are interpreted as empty documents, {}. Zend Json encoder will interpret them as empty arrays []. I understand that it's not possible to tell which one is correct.
In my view it's more logical that the actual php array (when empty) is interpreted as an array in MongoDB. Although that will require something else to identify empty documents it's still more logical than the current behaviour.
A possible solution would be to introduce a new object, MongoEmptyObject (or using the stdObj) whenever one want to introduce an empty object.
Meanwhile, a workaround is to detect empty arrays in php, and inject a null value $arr[0] = null;
Then the object will be interpreted as an empty array in mongo.
The workaround works both in PHP and in the mongo console. Question: does json allow for arrays with null values? If so, then the workaround is a sign of another bug.
PHP:
if (is_array($value) && empty($value))
{ $value[0] = null; }
Mongo Console:
var b =
{hej:"da", arr: [null]}
db.test.save(b);
db.test.find();
{"_id" : "4a4b23adde08d50628564b12" , "hej" : "da" , "arr" : []}