Node.js JSON.stringify variables not expanding - javascript

I am working on a node.js API for an app with a simple TCP server that accepts NDJSON (essentially delimited by '\r\n'). Anyway, I am having an issue with JSON stringify. I create an object (see below) with variables and then convert it to stringify. When I get the result, it's expanded all the variables except for "requestParamName." It's the only key, as opposed to being a value, and this is the result:
{"jsonrpc":"2.0","method":"Client.SetVolume","id":0,"params":{"client":"00:00:00:00:00:00","requestParamName":10}}
It should be this:
{"jsonrpc":"2.0","method":"Client.SetVolume","id":0,"params":{"client":"00:00:00:00:00:00","volume":10}}
I've tried several things, but I'm not sure what's causing it to not expand that particular variable. If anyone has any suggestions, I'd be grateful.
Function:
function ClientConnect(requestMethod, requestMacAddress, requestParamName, requestParamKey) {
var objectRequest = {
"jsonrpc": "2.0",
"method": requestMethod,
"id": 0,
"params": {
"client": requestMacAddress,
requestParamName: requestParamKey
}};
formattedJson = (JSON.stringify(objectRequest) + '\r\n');
console.log(formattedJson);
}
P.S. I'm new here so if I messed up the formatting, I apologize ;)

Actually doing :
"params": {
"client": requestMacAddress,
requestParamName: requestParamKey
}};
is exactly the same that :
"params": {
"client": requestMacAddress,
"requestParamName": requestParamKey
}};
You have to do like this (note that it's an ES6 feature - it's ok if you use a recent node.js):
var objectRequest = {
"jsonrpc": "2.0",
"method": requestMethod,
"id": 0,
"params": {
"client": requestMacAddress,
[requestParamName]: requestParamKey
}};
The ES5 version will be:
var objectRequest = {
"jsonrpc": "2.0",
"method": requestMethod,
"id": 0,
"params": {
"client": requestMacAddress
}};
objectRequest[requestParamName]= requestParamKey;

[variable] is what you need, otherwise it will be the same as above ^^

Related

Can't access variables of JSON response from REST-API in Javascript

I have a problem getting access to the variables in a JSON-File. I get the file as a response from a REST-API. Here you can see the JSON-File:
{
"_embedded": {
"events": [
{
"name": "Josh.",
"type": "event",
"id": "Z698xZC2Z17CebP",
"test": false,
"url": "https://www.ticketmaster.de/event/josh-tickets/382625?language=en-us",
"locale": "en-us"
I want to access the value (Josh) of the "name" variable in Javascript in line number 5 and store it into a new variable to use it later.
This ist how I try to do it:
var = data._embedded.events[0].name
But I can't get access to the value attached to "name".
I have read the answers to similar questions here, but there was no solution for me.
I have only read, that it does not work because of the wrong JSON-structure. In other threads, they say there has to be a "{" instead of a "[" in line 3. But I don't know how to change it in javascript directly. I tried it with the JSON.stringify()-method but it didn't work out.
Can somebody help me, please? Is there any way to get access?
I hope you can understand my problem.
Thank you very much!
It seems that your json structure has some errors. The json structure similar to the following is legal. Of course, it is no problem to use a legal structure to exec data._embedded.events[0].name.
const data = {
"_embedded": {
"events": [
{
"name": "Josh.",
"type": "event",
"id": "Z698xZC2Z17CebP",
"test": false,
"url": "https://www.ticketmaster.de/event/josh-tickets/382625?language=en-us",
"locale": "en-us"
},
{
"name": "Josh.",
"type": "event",
"id": "Z698xZC2Z17CebP",
"test": false,
"url": "https://www.ticketmaster.de/event/josh-tickets/382625?language=en-us",
"locale": "en-us"
},
//...
]
}
}
console.log(data._embedded.events[0].name)

Unsplash API triggering download

I'm following triggering guidelines in Unsplash documentation. So the endpoint is:
GET /photos/:id/download
This is the photo's example response:
{
"id": "LBI7cgq3pbM",
"width": 5245,
"height": 3497,
"color": "#60544D",
"urls": { ... },
"user": { ... },
"links": {
"self": "https://api.unsplash.com/photos/LBI7cgq3pbM",
"html": "https://unsplash.com/photos/LBI7cgq3pbM",
"download": "https://unsplash.com/photos/LBI7cgq3pbM/download", // don't use this property
"download_location": "https://api.unsplash.com/photos/LBI7cgq3pbM/download?ixid=MnwxMTc4ODl8MHwxfHNlYXJjaHwxfHxwdXBweXxlbnwwfHx8fDE2MTc3NTA2MTM" // use this one ;)
}
}
"Be sure to include any query parameters included in the URL (like the ixid)."
So my question is what is value od ixid=MnwxMTc4ODl8MHwxfHNlYXJjaHwxfHxwdXBweXxlbnwwfHx8fDE2MTc3NTA2MTM and how to get it?
Try the following
const ixid = new URLSearchParams(
new URL("https://api.unsplash.com/photos/LBI7cgq3pbM/download?ixid=MnwxMTc4ODl8MHwxfHNlYXJjaHwxfHxwdXBweXxlbnwwfHx8fDE2MTc3NTA2MTM").search
).get("ixid");
console.log(ixid);

Javascript parse JSON error, but works fine in validator

When I try to parse this JSON (Discord webhook):
{
"content": "this `supports` __a__ **subset** *of* ~~markdown~~ 😃 ```js\nfunction foo(bar) {\n console.log(bar);\n}\n\nfoo(1);```",
"embed": {
"title": "title ~~(did you know you can have markdown here too?)~~",
"description": "this supports [named links](https://discordapp.com) on top of the previously shown subset of markdown. ```\nyes, even code blocks```",
"url": "https://discordapp.com",
"color": 16324973,
"timestamp": "2018-12-18T09:22:12.841Z",
"footer": {
"icon_url": "https://cdn.discordapp.com/embed/avatars/0.png",
"text": "footer text"
},
"thumbnail": {
"url": "https://cdn.discordapp.com/embed/avatars/0.png"
},
"image": {
"url": "https://cdn.discordapp.com/embed/avatars/0.png"
},
"author": {
"name": "author name",
"url": "https://discordapp.com",
"icon_url": "https://cdn.discordapp.com/embed/avatars/0.png"
},
"fields": [
{
"name": "🤔",
"value": "some of these properties have certain limits..."
},
{
"name": "😱",
"value": "try exceeding some of them!"
},
{
"name": "🙄",
"value": "an informative error should show up, and this view will remain as-is until all issues are fixed"
},
{
"name": "<:thonkang:219069250692841473>",
"value": "these last two",
"inline": true
},
{
"name": "<:thonkang:219069250692841473>",
"value": "are inline fields",
"inline": true
}
]
}
}
Using this code:
var parsed = JSON.parse(req.body)
I get this error:
SyntaxError: Unexpected token o in JSON at position 1
But if I use a website such as
https://jsonformatter.curiousconcept.com
To validate the JSON, it says the JSON is valid.
What is wrong here?
UPDATE
I'm using an express server to simulate discord server, so it sends web hooks to the express server instead, I get the JSON using req.body.
This happens because JSON is a global object (it's the same object where you read the method parse!), so when you invoke JSON.parse(JSON) javascript thinks you want to parse it.
The same thing doesn't happen when you pass the variable to the validator, because it will be assigned to a local variable:
let JSON = "{}";
validate(JSON);
function(x) {
JSON.parse(x); // here JSON is again your global object!
}
EDIT
According to your updated question, maybe it happens because you already use bodyParser.json() as middleware, and when you use it, req.body is already an object and you don't need to parse it again.
Trying to parsing an already parsed object will throw an error.
It would be something like without using JSONStream:
http.request(options, function(res) {
var buffers = []
res
.on('data', function(chunk) {
buffers.push(chunk)
})
.on('end', function() {
JSON.parse(Buffer.concat(buffers).toString())
})
})
For using it with JSONStream, it would be something like:
http.request(options, function(res) {
var stream = JSONStream.parse('*')
res.pipe(stream)
stream.on('data', console.log.bind(console, 'an item'))
})
(OR)
Here is the Some Steps for this issue..
You Can use lodash for resolving this.
import the lodash and call unescape().
const _ = require('lodash');
let htmlDecoder = function(encodedStr){
return _.unescape(encodedStr);
}
htmlDecoder(JSON);

Simplify an associative array

I'm hitting an api built using CakePHP. Cake returns its objects like this:
[
{
"Note": {
"id": "1",
"clas": "test",
"obj_id": null,
"note": "test"
}
},
{
"Note": {
"id": "2",
"clas": "another",
"obj_id": null,
"note": "another"
}
}
]
What I want to do is take that result and basically get rid of the keys. Something like this:
[
{
"id": "1",
"clas": "test",
"obj_id": null,
"note": "test"
},
{
"id": "2",
"clas": "another",
"obj_id": null,
"note": "another"
}
]
I'm basically just trying to make it easier to reference this in Angular. I need to do this on the client side. Any ideas?
You could refactor it like so:
var json = '[{"Note":{"id":"1","clas":"test","obj_id":null,"note":"test"}},{"Note":{"id":"2","clas":"another","obj_id":null,"note":"another"}}]';
var obj = JSON.parse(json);
var arr = [];
for (i = 0; i < obj.length; i++)
{
arr.push(obj[i].Note);
}
Working example here
(Note also that if your key value 'Note' isn't always the same, this will change dramatically. It's likely that 'Note' isn't going to be the same in each instance either; that would generate an improperly keyed object. Alternatively, if you always need the first object in the array, you could use obj[i][0] instead).
(More note if you're using cakephp, this would be much easier done using Hash::, but if you need to do it client side, this is the solution).

constructor from json schema

Is there a way to build object constructors from a JSON schema? I want to create a json schema associated with my application's namespace that I can edit once, and change the properties(before runtime) of my objects.
I know that you can write a pseudo classical object constructor like
var Note = function(input){
var title = input
};
var newNote = new Note("test title");
Is it possible to create a similar structure from json? Such that I can write:
var Note = {
"title":""
};
var newNote = new Note();
newNote.title = "test title"
I understand that this above is syntactically wrong, but I would like to for example have:
var notes = {
"NotesList":[{
"title":"note1",
"content":"test content"
}]
}
var newNote = new Note();
notes.NotesList.add(newNote);
newNote.title = "new title";
so that I can base all my objects and all of their children off of this object template created from my json schema. If this is not possible, can you recommend a better method?
I'm not sure that I understood your question completely. However if you wish to convert a function into JSON then yes, that's definitely possible.
All you need to do is use a JavaScript parser like acorn which uses the Mozilla Parser API to generate an abstract syntax tree of your constructor in JSON format. For example:
var ast = acorn.parse(Note);
var json = JSON.stringify(ast, null, 4);
alert(json);
function Note(input) {
var title = input;
}
See the demo here. The above code produces the following output:
{
"type": "Program",
"start": 0,
"end": 47,
"body": [
{
"type": "FunctionDeclaration",
"start": 0,
"end": 47,
"id": {
"type": "Identifier",
"start": 9,
"end": 13,
"name": "Note"
},
"params": [
{
"type": "Identifier",
"start": 14,
"end": 19,
"name": "input"
}
],
"body": {
"type": "BlockStatement",
"start": 21,
"end": 47,
"body": [
{
"type": "VariableDeclaration",
"start": 27,
"end": 44,
"declarations": [
{
"type": "VariableDeclarator",
"start": 31,
"end": 44,
"id": {
"type": "Identifier",
"start": 31,
"end": 36,
"name": "title"
},
"init": {
"type": "Identifier",
"start": 39,
"end": 44,
"name": "input"
}
}
],
"kind": "var"
}
]
}
}
]
}
You can save the above AST in a JSON file and load it as and when required. You can use escodegen to convert the AST back to JavaScript as follows:
alert(escodegen.generate(ast));
See the demo here. You may then eval the generated code and use the Note constructor as you wish.
I found the answer to what I was looking for. My ultimate goal was to make an object with arrays of children, each of which could have children etc. The object would then be used as the namespace to my entire application like:
var myobj = {};
I wanted to use JSON to specify the properties of this object, and then build constructors off of these properties like:
var myObj = {
"name": "genericname",
"id": "uniqueid",
"children": [
{
"grandchildren": [
{
"name": "child",
"age": "0"
}
]
}
]
};
What I ended up doing was, building constructor functions from this, and then cloning them into my new objects so they could have these default values like this:
myObj.Child = function(){
var child = myObj.children[0];
return child;
//this is the unmodified constructor child
};
var myObj.createChild = function(){
var newChild = new Clone(myObj.Child());
//do stuff to this is new child which can be modified without changing the original
return newChild;
};

Categories

Resources