Problems with object JSON conversion - json

I have one object (jar), which contains this (by console.log):
{ _jar: { store: { idx: { localhost: { '/': { PHPSESSID: Cookie="PHPSESSID=pe1952pk023e7b6d7t9am3kse0; Path=/; hostOnly=true; aAge=18ms; cAge=97ms" } } } } } }
I'm trying to store it to MongoDB instance which is ok, but after loading it from there, it's kind of malformed. This simulates it:
console.log(JSON.parse(JSON.stringify(jar)));
The above outputs this:
{ _jar: { store: { idx: [Object] } } }
So all of the sudden 'localhost' part got vanished into 'Object'? How to prevent this?

console.log doc says:
If formatting elements are not found in the first string then
util.inspect is used on each argument.
util.inspect doc says:
Return a string representation of object, which is useful for
debugging.
[...]
depth - tells inspect how many times to recurse while formatting the object. This is useful for inspecting large complicated objects.
Defaults to 2. To make it recurse indefinitely pass null.
That is, console.log(jar) prints only the first two levels, _jar and store, and the fields of store are printed in short format. That's why the content of store.idx is printed as [Object]. To print every level, type util.inspect(jar, { depth: null }).

That console.log formatting, not a JSON.parse problem.
console.log(jar) will give you the same output.

Related

What counts as an object vs a string in Typescript?

I am creating a Infrastructure-as-Code for a Step Functions Machine. One of these states is of type 'Task' which performs a DynamoUpdateItem on a DynamoDB table.
The code looks as following:
const updateDDB = new tasks.DynamoUpdateItem(this, 'Update item into DynamoDB', {
key: { ['Task'] : tasks.DynamoAttributeValue.fromString('Processing') },
table: table,
updateExpression: 'SET LastRun = :label',
expressionAttributeValues: {
':label.$': DynamoAttributeValue.fromString(JsonPath.stringAt('$$.Execution.StartTime')),
},
resultPath: JsonPath.DISCARD,
});
However, I keep getting an error saying the schema validation failed, and that
"The value for the field ':label.$' must be a STRING that contains a JSONPath but was an OBJECT at /States/Update item into DynamoDB/Parameters'"
How the heck is it not a string?!
I have tried writing it as [':label.$'],
or even writing a .toString() function at the end of the JsonPath method
expressionAttributeValues: {
':label.$': (DynamoAttributeValue.fromString(JsonPath.stringAt('$$.Execution.StartTime').toString())),
},
But nothing seems to work. I keep getting the same issue claiming that it's not a string.
Using something like JSON.stringify() doesn't work either because expressionAttributeValues takes a key and matches it with a DynamoAttributeValue.
TL;DR Drop the .$ suffix from ':label.$': DynamoAttributeValue(...) in the expression attribute value definition. The key should be simply ':label'.
As #TobiasS says in the comments, the problem is with your State Machine task syntax. The .$ suffix on :label.$ tells AWS to expect a JSONPath string representing a path to a value. But a string is not valid State Machine syntax for this field. A key-value pair is required. The CDK docs have an example with the correct syntax.
❌ What your CDK code synthesizes to:
{
"ExpressionAttributeValues": {
":label.$": { "S.$": "$$.Execution.StartTime" }
},
}
✅ AWS expects the synthesized State Machine definition to be:
{
"ExpressionAttributeValues": {
":label": { "S.$": "$$.Execution.StartTime" }
},
}

Issue with formatting json array in new file

After creating a new file for json, I am needing to create two arrays, when creating the first one, an error popped up where it doesn't want to accept type1:[ as the array's start.
Tried using a validator, inside, I switched to a comma after it confirmed the error, that didn't give the desired effect.
{
"type1":[
"product1":{
},
"product2":{
},
"product3":{
}
]
}
It threw up an error message when I expected to be able to expand on products and then have the basic system to practice with.
{
"type1":[
{
"product1":{
}
},
{
"product2":{
}
},
{
"product3":{
}
}
]
}
Please use this format. your format is invalid. as #kmr said
"JSON arrays cant contain key value pairs"

Error: Converting circular structure to JSON

I have a problem with my application. Anyone can help me?
Error:
Converting circular structure to JSON
My Service to create items and save on localstorage:
addItem(item: Item): void {
this.itens.unshift(item);
let itens;
if (localStorage.getItem('itens') == null){
itens = [];
itens.unshift(itens);
localStorage.setItem('itens', JSON.stringify(itens));
} else {
JSON.parse(localStorage.getItem('itens'));
itens.unshift(itens);
localStorage.setItem('itens', JSON.stringify(itens));
}
}
And my component.ts:
addItem(): void {
this.itemAdicionado.emit({
nome: this.nome,
unidade: this.unidade,
quantidade: this.quantidade,
preco: this.preco,
perecivel: true,
validade: this.validade,
fabricacao: this.fabricacao,
});
this.nome = '';
this.unidade ;
this.quantidade ;
this.preco;
this.validade;
this.fabricacao;
console.log(this.nome, this.unidade, this.quantidade, this.preco, this.validade, this.fabricacao);
}
This isn't an Angular error. It's a JavaScript runtime error thrown by the JSON.stringify function. The error tells you that itens contains a circular object reference. This is OK while you run the application, but when stringifying it causes a problem: the JSON generated would become infinitely long.
As Kevin Koelzer indicated in his answer. The problem is that you wrote itens.unshift(itens);. Basically this adds the array of items to the array of items, thus creating a circular reference. Therefore, writing itens.unshift(item); instead solves your problem and is probably what you intended to do anyway.
itens.unshift(itens);
could this be:
itens.unshift(iten);

Understanding of JSON array iteration in TypeScript

I would like to understand what I did wrongly. I have tried to read this, but it was overwhelmingly detailed:
Access / process (nested) objects, arrays or JSON
{
"dogs":[
{
"name": "shiba",
....
}
{
"name": "akita",
....
}
]
}
I read the JSON from an HTTP server and it was returned as data.
for(var item in data["dogs"])
{
console.log(item["name"]);
console.log(data["dogs"][0]["name"]);
}
console.log(item["name"]); does not work, returning 'undefined'. console.log(data["dogs"][0]["name"]); works, but since it has a fixed index, it does not iterate all names. Why isn't the first one working?
In VS Code, if I set a breakpoint at that line, somehow the breakpoint does not stay. It gets hit but continues away in a second, so I cannot examine the data. Before running, if I place the mouse on item, the popup says that the type is string. Why is it a string; shouldn't it be 'any'?

How to avoid "Unable to get property 'X' of undefined or null reference" when creating $scope properties from JSON data

I want to populate some charting data from some JSON data pulled down using $http.get. However, the issue I have is the $scope property I am binding to doesn't exist until the JSON is returned, so the page is throwing an error when it loads.
How do I avoid the error? It feels like I have a chicken and egg scenario.
Example:
$scope.Model.Charts.Electricity = {
series: [
name: "2014 Target",
data: $scope.Model.Data.Json.Charts.Electricity.CurrentYearTarget
]
};
The Electricity.CurrentYearTarget property is the one that doesn't exist until the promise is completed:
promise.then(
function(payload) {
$scope.Model.Data.Json.Charts = payload.data;
});
The JSON is what then defines the objects that sit under .Charts. Example:
{"Electricity":
{"CurrentYearTarget":
[10000.0,
// snip
10000.0]
}
}
OK, so what can I do to work with this? I suppose I could wrap all of my properties like $scope.Model.Charts.Electricity and so forth into a simple JavaScript if statement, but that doesn't feel right.
I suggest you consider simplifying your approach somewhat, as $scope.Model.Data.Json.Charts.Electricity.CurrentYearTarget is somewhat verbose, and Model, Data, Json all mean the same thing really, you can probably cut some of these out.
However, this is beside the point, you can still acheive what you want to, just populate the data when the request has returned:
$scope.Model = { Data: { Json: { Charts: {} } } }
promise.then(
function(payload) {
$scope.Model.Data.Json.Charts = payload.data;
$scope.Model.Charts.Electricity = {
series: {
name: "2014 Target",
data: $scope.Model.Data.Json.Charts.Electricity.CurrentYearTarget
}
};
});