I have json files where the various fields can change.
"eventHistory": [{
"occurredAt": "2018-03-17T10:40:05.707 0000",
"calluuid": "G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"eventId": "2018-03-17T10:40:05.707Z_1521283205_G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"event": "Data",
"data": {
"added": {
"OtherTrunkName": "sbc-trunk",
"OriginationDN": "1234",
"BusinessCall": "0",
"OriginationDN_location": "MNLSwitch"
}
}
}, {
"occurredAt": "2018-03-17T10:40:06.033 0000",
"calluuid": "G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"eventId": "2018-03-17T10:40:06.033Z_1521283206_G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"event": "Data",
"data": {
"added": {
"IW_CaseUid": "04d575ba-32e3-48da-8986-a19a6ff493b3",
"IW_BundleUid": "bf3ac19e-e2ea-4d7b-9b48-ef5e17dfdaa1"
}
}
}, {
"occurredAt": "2018-03-17T10:40:10.407 0000",
"calluuid": "G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"eventId": "2018-03-17T10:40:10.407Z_1521283210_G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"event": "Data",
"data": {
"added": {
"WrapUpTime": "0"
},
"deleted": {
"OriginationDN_location": "MNLSwitch",
"OriginationDN": "1234"
}
}
},
Is there an 'easy' way to simply read through and add these as variables to a js. I gather each field and then post to PHP which saves.
then I need to display in a tree... another question likely to appear on that one too.
Any help much appreciated.
It is unclear if you require the variables to be declared in a JS file, or if you simply want each key and value pair to be extracted out. Thus, I've provided 2 approaches that could be useful for your use case.
Suggestion: If it doesn't matter, why not handle the whole JSON object in your PHP save script?
1. Extract Key Value pairs
If you require a recursive JS function to get all the keys and values, you may use this function, referenced from here.
Caveat: This function ignores keys with nested key value pairs, so you will need to modify it to suit your needs.
var json = `
{
"occurredAt": "2018-03-17T10:40:06.033 0000",
"calluuid": "G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"eventId": "2018-03-17T10:40:06.033Z_1521283206_G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"event": "Data",
"data": {
"added": {
"IW_CaseUid": "04d575ba-32e3-48da-8986-a19a6ff493b3",
"IW_BundleUid": "bf3ac19e-e2ea-4d7b-9b48-ef5e17dfdaa1"
}
}
}
`
var obj = JSON.parse(json);
iterate(obj,'');
function iterate(obj, stack) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property], stack + '.' + property);
} else {
console.log(property + " " + obj[property]); //get key and value pair here
}
}
}
}
2. Declare Variables in JS
If you require variables to be declared in a JS <script> tag, you can consider using PHP to generate a HTML page with the variables declared.
The code below produces a html file with the following script tag:
Advantage: This approach allows you to get creative, and generate a lot of JS code that is variable specific.
Disadvantage: Debugging this could be hard.
Caveat: The example below is not recursive, so you'll have to do that on your own.
<?php
$string = <<<EOD
{
"occurredAt": "2018-03-17T10:40:06.033 0000",
"calluuid": "G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"eventId": "2018-03-17T10:40:06.033Z_1521283206_G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"event": "Data",
"data": {
"added": {
"IW_CaseUid": "04d575ba-32e3-48da-8986-a19a6ff493b3",
"IW_BundleUid": "bf3ac19e-e2ea-4d7b-9b48-ef5e17dfdaa1"
}
}
}
EOD;
$json = json_decode($string);
echo '<script>';
foreach($json as $key => $value)
{
$output = <<<EOD
var $key = "$value";
EOD;
echo $output;
}
echo '</script>';
?>
Related
I have an API gateway that scans a DynamoDB table. I want to pass LastEvaluatedKey in my request body; if I pass a LastEvaluatedKey then the everything works and I get a response with the expected data - so I'm half way there.
But, of course, the first time I send a request to the API LastEvaluatedKey will not exist, so the ExclusiveStartKey in the mapping template that expects a LastEvaluatedKey must be optional. I've tried a few different ways to get this to be optional but nothing has worked so far. Here is what I have:
#set($hasName = $input.json('$.Name'))
{
"TableName": "MyTable",
#if($hasName && $hasName.length() != 0)
"ExclusiveStartKey": {
"Name": {
"S": $input.json('$.Name')
},
"Date": {
"S": $input.json('$.Date')
}
},#end
"FilterExpression": "begins_with(#dt, :tdt)",
"ExpressionAttributeNames": {
"#dt": "Date"
},
"ExpressionAttributeValues": {
":tdt": {
"S": "$input.params('date')"
}
}
}
As I say, the above works when I do pass a LastEvaluatedKey in my request body, but when I do not I get the error:
{
"__type": "com.amazon.coral.validate#ValidationException",
"message": "The provided starting key is invalid: One or more parameter values were invalid: An AttributeValue may not contain an empty string"
}
...it's still expected the LastEvaluatedKey
I've also tried wrapping Name and Date inside if #if but with no luck at all. I've taken inspiration from other answers such as: this and this, but no luck.
In my example cursor is the LastEvaluatedKey:
#set($hasCursor = $input.params('cursor') != "")
{
"TableName": "my-table"
#if($hasCursor) "ExclusiveStartKey":$util.base64Decode("$input.params('cursor')")
#end
}
It just checks if cursor is passed as a query param (like /my/api?cursor=myencodedlastevaluatedkey), and only adds ExclusiveStartKey to the request if it is.
If you know beforehand that both keys are string type, you can do:
#set($Name = $input.params('Name'))
#set($Date = $input.params('Date'))
{
#if($Name != '' && $Date != '')
"ExclusiveStartKey": {
"Name": {
"S": "$Name"
},
"Date": {
"S": "$Date"
}
},
#end
#if($Date != '')
"FilterExpression": "begins_with(#dt, :tdt)",
"ExpressionAttributeNames": {
"#dt": "Date"
},
"ExpressionAttributeValues": {
":tdt": {
"S": "$Date"
}
}
},
#end
"TableName": "MyTable"
}
This makes the filter optional, only if Date is passed as argument
I have a VP/MS MySQL table with a "ref" column incorporating a unique identifier and a "request" column essentially incorporating a complete JSON response message in BLOB format. The message looks like this:
{
"vars": {
},
"computes": {
"P_PRERefId_str": {
"=": "12421321"
},
"P_PolicyNumber_str": {
"=": "1234567890"
},
"P_YearlyPolicyFeeAmt_rea": {
"=": "70.56"
}
}
}
Is there a way that I can somehow extract the JSON key-value pairs into 3 columns and corresponding values like:
P_PRERefId_str P_Policy P_YearlyPolicyFeeAmt_rea
12421321 1234567890 70.56
This might be what you are looking for. First, turn your JSON into a PHP object.
$myObject = json_decode('{
"vars": {},
"computes": {
"P_PRERefId_str": {
"=": "12421321"
},
"P_PolicyNumber_str": {
"=": "1234567890"
},
"P_YearlyPolicyFeeAmt_rea": {
"=": "70.56"
}
}
}');
Then, iterate through the "computes" attribute and insert the properties into your DB.
foreach ($myObject->computes as $column => $attr) {
foreach ($attr as $equalSign => $val) {
// INSERT $val INTO $column
// Depending on your Driver (PDO, framework ORM)
// Your code will differ here
}};
I am using mongoose as JSON Schema and node.js with it. Need not say, I am new to both. I have been struggling through the day to get this thing work for me but couldn't. Finally, the only solution was to get help from some real nice people out here.
Here is my schema definition -
UserName = {
"properties": {
userURL: {
"description": "URL of this resource",
"type": "string"
},
userName : {
"description": "UserName",
"type": "string",
"required": true
},
}
}
When I make a get call to it, it returns the response in following format -
[
{
"_id": "54c5ede55c82c4bd6abee50a",
"__v": 0,
"properties": {
"userURL": "http://localhost:3000/54c1d6ae441ae900151a6520",
"userName ": "testUser"
}
}
]
Now my requirement is to return the response in following format -
[
{
"_id": "54c5ede55c82c4bd6abee50a",
"userURL": "http://localhost:3000/54c1d6ae441ae900151a6520",
"userName ": "testUser"
}
]
i.e without version and properties tags. I am able to get away with version using following code but properties seems to be tricky thing -
.get(function(request, response) {
UserSchemaModel.find().select('properties.userURL properties.userName').exec (function (err, resObj) {
if (err)
response.send(err);
else{
response.json(resObj);
}
});
});
But it still has properties field :( -
[
{
"_id": "54c5ede55c82c4bd6abee50a",
"properties": {
"userURL": "http://localhost:3000/54c1d6ae441ae900151a6520",
"userName ": "testUser"
}
}
]
I did some google around select as, alias name in select,population in mongoose but no luck.
Kindly suggest. With best Regards.
Just make a new object
response.json(
{
"_id": resObj["_id"],
"userURL": resObj["properties"]["userUrl"],
"userName": resObj["properties"]["userName"]
}
);
Update: Since resObj is an array (as per your comment), you can use Array.prototype.map() to transform them into the right format like so:
response.json( resObj.map(function(o){
return {
"_id": o["_id"],
"userURL": o["properties"]["userUrl"],
"userName": o["properties"]["userName"]
};
})
);
This will return a list of transformed objects that then get passed into the response.json() method.
My json data is as follows:
"query": {
"count": 1,
"url": [
{
"execution-start-time": "1"
},
{
"execution-time": "745"
}
],
"service-time": "1481"
},
results": {
"div": {
"class": "makers",
"ul": {
"li": [
{
"a": {
"href": "nokia_x2_dual_sim-6383.php",
"img": {
"src": "Nokia-X2-Dual-SIM.jpg"
},
"strong": {
"br": null,
"content": "Nokia\nX2 Dual SIM"
}
}
},
{
"a": {
"href": "nokia_xl-6148.php",
"img": {
"src": "nokia-xl.jpg",
},
"strong": {
"br": null,
"content": "Nokia\nXL"
}
}
}
]
Now I want to extract the "content" part from this json data using jsonpath.I am using jsonpath-0.8.0.js for this purpose.
I have tried to parse the json data in the following way:
function ParseData(data) {
var result = jsonPath(data, "$.query.results[*].ul.li[*].strong.content");
$('#carousel').empty();
var html = "";
for (i = 0; i < result.length; i++) {
// do something
}
and I was expecting to get Nokia\nX2 Dual SIM and Nokia\nXL as output but this code of mine does not return anything.I cannot understand the problem.
How do I extract the content data from this json? please help.
Friends, I finally got the answer to my problem.I used the following code to extract content from the above given json data.
var result = jsonPath(data, "$.query.results[*].ul.li[*].a.strong.content");
Now I am getting the output data as expected.
I am building a JSON-based REST API using Symfony2.4 with Doctrine2.
EDIT : with JsonNormalizer, I can disabled some attributes, but what if I would like to set them, without recursivity ?
Basically, what I have (working) now is :
{
"tasks": [
{
"id": 1,
"name": "first task"
},
{
"id": 2,
"name": "second task"
}
]
}
What I would like is :
{
"tasks": [
{
"id": 1,
"name": "first task",
"category": {
"id": 1,
"name": "first category"
}
},
{
"id": 2,
"name": "second task",
"category": {
"id": 1,
"name": "first category"
}
}
]
}
What was my initial problem is :
{
"tasks": [
{
"id": 1,
"name": "first task",
"category": {
"id": 1,
"name": "first category",
"tasks": [
{
"id": 1,
"name": "first task",
"category": {
"id": 1,
"name": "first category",
"tasks": [...] // infinite...
}
},
{
"id": 2,
"name": "second task",
"category": {
"id": 1,
"name": "first category",
"tasks": [...] // infinite...
}
}
]
}
},
{
"id": 2,
"name": "second task",
"category": {
"id": 1,
"name": "first category",
"tasks": [
{
"id": 1,
"name": "first task",
"category": {
"id": 1,
"name": "first category",
"tasks": [...]
}
},
{
"id": 2,
"name": "second task",
"category": {
"id": 1,
"name": "first category",
"tasks": [...]
}
}
]
}
}
]
}
I have a entity A with a manyToOne relation to another entity B.
I have implemented the reverse-side, to be able to retrieve the related A entities on the B one.
class Task
{
/**
* #ORM\ManyToOne(targetEntity="List", inversedBy="task")
* #ORM\JoinColumn(name="list_id", referencedColumnName="id")
*/
private $list;
public function toArray($recursive = false)
{
$entityAsArray = get_object_vars($this);
if ($recursive) {
foreach ($entityAsArray as &$var) {
if ((is_object($var)) && (method_exists($var, 'toArray'))) {
$var = $var->toArray($recursive);
}
}
}
return $entityAsArray;
}
}
use Doctrine\Common\Collections\ArrayCollection;
class List
{
/**
* #ORM\OneToMany(targetEntity="Task", mappedBy="list")
*/
private $tasks;
public function __construct()
{
$this->tasks = new ArrayCollection();
}
}
Then I am building the different API routes and controllers,
Rendering the output as JsonResponses,
And I would like to render, for a given list, the different tasks using the route :
/api/v1/lists/1/tasks
The task action of my controller :
public function tasksAction($id)
{
$em = $this->getDoctrine()->getManager();
$list = $em->getRepository('MyRestBundle:List')->findOneActive($id);
if (!$list) {
throw $this->createNotFoundException('List undefined');
}
$tasks = $list->getTasks()->toArray();
foreach ($tasks as &$task) {
// recursively format the tasks as array
$task = $task->toArray(true);
}
$serializer = $this->get('serializer');
return $this->generateJsonResponse($serializer->normalize($tasks), 200);
}
But unfortunately, I always get a memory leak, because the call of toArray() is recursive, so each task has a list property which has a tasks collection etc.
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 130968 bytes) in src/Symfony/Component/Serializer/Serializer.php on line 146
I am wondering what would be the cleanest way to render entities with relations as JSON objects with Symfony2 ?
Do I really have to loop on my tasks to execute the "toArray()" method ?
I have also tried without it, without more success, except that the leak in in the file : src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php...
I have also tried without the JMSSeralizer, and the memory leak is thrown in my own php file.
Of course, I could increase the memory limit, but as it is an infinite loop problem of toArray() calls, it will not solve my problem.
How to format it properly ?
I have a feeling that we might be overthinking this. Would that work for you?
// In your controller
$repo = $this->getDoctrine()->getRepository('MyRestBundle:List');
$list = $repo->findActiveOne($id);
$tasks = $list->getTasks()->toArray();
$serializer = $this->get('serializer');
$json = $serializer->serialize($tasks, 'json');
Why is Task Entity recursive? A task can not include another task. Only a List can include an array of Tasks. So basically all we should do is get this array from the List entity and serialize it. Unless I am missing something.
EDIT:
You can ask the serializer to ignore certain attributes as mentioned by the documentation:
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
$normalizer = new GetSetMethodNormalizer();
$normalizer->setIgnoredAttributes(array('age'));
$encoder = new JsonEncoder();
$serializer = new Serializer(array($normalizer), array($encoder));
$serializer->serialize($person, 'json'); // Output: {"name":"foo"}
Try to follow that example and just ignore the $list attribute in the Task entity.
EDIT2:
You don't need 'list' inside each task since it's the same. Your json should have 'list' and 'tasks' at the same level. then 'tasks' would be an array of tasks which will not contain 'list'. to achieve that you can have something like array('list' => $list, 'tasks' => $tasks) and serialize that.
EDIT
If I understand what your code is doing, I think the toArray($recursive) function goes into infinite recursion both directly (whenever $var = $this) and indirectly (i.e. by a sibling iterating through its own list and calling toArray of the original task again). Try keeping track of what's been processed to prevent infinite recursion:
/**
* #ORM\ManyToOne(targetEntity="List", inversedBy="task")
* #ORM\JoinColumn(name="list_id", referencedColumnName="id")
*/
private $list;
private $toArrayProcessed = array();
public function toArray($recursive = false)
{
$this->toArrayProcessed[$this->getId()] = 1;
$entityAsArray = get_object_vars($this);
if ($recursive) {
foreach ($entityAsArray as &$var) {
if ((is_object($var)) && (method_exists($var, 'toArray')) && !isset($this->toArrayProcessed[$var->getId()]) {
$var = $var->toArray($recursive);
}
}
}
return $entityAsArray;
}