Not able to pass an object in writeFile method - javascript

I want to write into json file .I want to write an object that i am passing
Here is the code
path.exists(logfile_name, function(exists) {
if (!exists) {
var jsonObject={ "req": req,
"result": result ,
"fields": fields } ;
fs.writeFile(logfile_name ,jsonObject,function(err){
if(err){
console.log("error is: " + err)
}
else
console.log("no error found");
});
}
});
In logfile_name it writes
[object Object]
But i want it to write like this
{
"req": value,
"result": value ,
"fields": value}

If you don't pass a string or a buffer to writeFile, the toString function of what you pass is called. In your case it returns "[object Object]".
You have to convert it yourself :
fs.writeFile(logfile_name, JSON.stringify(jsonObject), function(err){
I would advise against naming a JavaScript object variable "jsonObject" : it might create confusion between what is an object and what is some JSON (i.e. a string holding the serialization of an object).

Related

Copied JSON data shows as string in node js / javascript

I wrote a code where I am copying a one json file into another json file so my code look like this
function userData(){
fs.copyFile(
path.join(process.cwd(), "user/access.json"),
path.join(process.cwd(), "client/access.json"),
(err) => {
if (err) throw console.log(err.message);
}
);
}
so my json structure look like this
{
"Data":{
"users":[
{},
{},
{},
]
}
}
So I am reading json the copied json file like this
fs.readFile(path.join(process.cwd(), "client/access.json"), 'utf8', function(err, data){
console.log(typeof data); // showing as a string as it should shown me as object
// console.log(data.Data.users); // showing undefined
});
but the problem is the typeof of data showing me string as it should be shown as Object so I can read the data.Data.users but now I can't read this any solution whats happening here?
What you read file file is always a string. To convert it to an JSON object you need to do JSON.parse
fs.readFile(path.join(process.cwd(), "client/access.json"), 'utf8', function(err, data){
console.log(typeof data); // showing as a string as it should shown me as object
const obj = JSON.parse(data);
console.log( typeof obj);
// console.log(data.Data.users); // showing undefined
});

Argument passed in must be a string of 12 bytes

Hello guys i'm getting this message when i'm trying to delete an entry in my DB.
I have tried JSON.parse on the req.body,switched the routes in my routes file yet nothing seems to work.
this is my controller :
async function removeToy(req, res) {
try {
const { toyId } = req.params
const removedId = await toyService.remove(toyId)
res.send(removedId)
} catch (err) {
logger.error('Failed to remove toy', err)
res.status(500).send({ err: 'Failed to remove toy' })
}
}
this is the service :
async function remove(toyId) {
try {
const collection = await dbService.getCollection('toy')
await collection.deleteOne({ '_id': ObjectId(toyId)})
return toyId
} catch (err) {
logger.error(`cannot remove toy ${toyId}`, err)
throw err
}
}
also added a picture of how the DB looks like:
and the picture of the entire error :
appreciating any kind of help!
In your database you have an object whose _id is of type string.
In your query, you're casting (presumably) a string to an ObjectID, which is an object. Not only is the argument you're passing to ObjectId() not something that it supports (as the error indicates, see below), even if it would be valid, the query would result in 0 hits: after all "TZ23c" !== ObjectId("TZ23c").
Simply change .deleteOne({_id: ObjectId(toyId)}) to .deleteOne({_id: toyId}).
ObjectId() either takes no argument (it will return a new value) or it takes exactly 12 bytes (24 hexadecimal characters), for example: ObjectId("61e16f21f82a9db6a2094e78").
An ObjectId's string representation (ObjectId().toString()) is not an arbitrary string of characters: it's a timestamp, some values that identify which server generated it and some random values to prevent collisions. Not every string is a valid ObjectId.
As the message suggest your toyId passed to the function is with wrong lenght , it must be 12 bytes long , example:
mongos> ObjectId("x448c")
2022-01-14T13:43:51.427+0100 E QUERY [js] Error: invalid object id: length
:
#(shell):1:1
mongos>
The correct is:
mongos> ObjectId("61e16facafe3aa6023c221bb")
ObjectId("61e16facafe3aa6023c221bb")

How can I use all function arguments inside javascript Object.assign method

I am making a server using nodejs & express in which user can request some data and server send response. But, the data is array and I want to send a json response to the user. So, I used forEach() method of array and use Object.assign(), so that I can get object. But the problem is I cannot use 'index' argument of forEach() method while 'value' argument is properly getting used inside the callback function. When I use only 'index' argument, then my code runs ok but I want to use both arguments at the same time.
route.get('/getGPX/:number', passport.authenticate('jwt', { session: false }), (req, res) => {
gpx.find({ username: req.user.username }, (err, result) => {
if (err) console.log(err);
if (result) {
if (result.length === 0) {
res.end();
console.log('ended')
}
else {
var jsonRes = {};
result.forEach((value, index) => {
I can use 'value' but not 'index' from the arguments
jsonRes = Object.assign({ index: value.data }, jsonRes);
})
res.json({data: jsonRes});
}
}
})
I even tried using global var, but even it's not working, how can I use index as well as value argument at the same time
What is the JSON structure that you want ?
if you want a json like :
{
0: "my first value",
1: "second"
}
You just miss [] around index, here you put 'index' as a key not the value of index. So you override the index key in each iteration.
Here is the code that use the value of index as a key in a json.
jsonRes = Object.assign({[index]: value.data}, jsonRes)
See here for a working example with more examples : https://repl.it/#Benoit_Vasseur/nodejs-playground
Object.assign mutates the left-most parameter. it does not produce a new object. Since you are passing a literal object every time the jsonRes is going to be the last result.
Put jsonRes in the left instead - Object.assign(jsonRes, {index: value.data})
You might want to use a simple reduce instead of forEach and Object.assign:
} else {
var jsonRes = result.reduce((r, v, i) => {r[i] = v.data; return r}, {});
res.json({data: jsonRes});
}

Access second level child in Json based on a variable

I'm currently working on a configuration service in my Angular 2 application, my current concern is about the utilization of eval in my code to retrieve a value in my configuration.
Here's a sample of my configuration file:
{
"application": {
"environment": "dev",
"displayMenu": false
},
"error": {
"title": "Title Error",
"message": "Error message"
}
}
I'm retrieving this JSON with a simple HTTP request, but now I would like to access an element with my get method defined like this:
get(key: any) {
return (eval("this._config." + key));
}
As you can see, there is an eval in my code that I would like to avoid. I'm forced to use eval to allow the developer to do .get('application.environment') and actually I don't find any others an easy possibility.
The only other way that I could see is to split the key on a "." and retrieve the right element in my JSON like it was a simple array. But with this solution, I would be stuck to one depth only.
You could use an array of your object keys you wish to view, then reduce that array returning the key of the object. If you wish to have a string as the object accessors you can easily use string.split('.') to create the array you can reduce.
const data = {
"application": {
"environment": "dev",
"displayMenu": false
},
"error": {
"title": "Title Error",
"message": "Error message",
"deeper": {
"evenDeeper": "You can get to any level"
}
}
}
const path = (keys, obj) => {
return keys.reduce((obj, key) => {
return typeof obj !== 'undefined'
? obj[key]
: void 0
}, obj)
}
console.log(
path(['application', 'environment'], data)
)
console.log(
path('error.message'.split('.'), data) // move the split inside the path function
)
console.log(
path(['error', 'deeper', 'evenDeeper'], data)
)
console.log(
path(['error', 'fail', 'damn'], data) // fail safe
)
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>

How to get JSON Elements from String(full with JSON object).

I have a JSON file
{ "impressions":
[
{
"impressionId": "7ad7a77fas346a7a2a1da6",
"userId": "hafsa",
"clientId": "400"
},
{
"impressionId": "7ad7a77fas346a7a2a1da7",
"userId": "asif",
"clientId": "200"
},
{
"impressionId": "7ad7a77fas346a7a2a1da8",
"userId": "zadarov",
"clientId": "300"
},
{
"impressionId": "7ad7a77fas346a7a2a1da9",
"userId": "julia",
"clientId": "100"
}
]
}
I am working on Kafka and have a NodeJS Producer and Java Consumer.I have to get each impression as a separate message in my consumer. My nodeJS code is:
console.log("Kafka is recieving JSON....");
var fs = require('fs');
var kafka = require('kafka-node');
var Producer = kafka.Producer;
var Client = kafka.Client;
var client = new Client('localhost:2181');
var producer = new Producer(client);
fs.readFile('data.json', 'utf8', function (err, data) {
if (err) throw err;
var jsonobj = JSON.parse(data);
var countMessages = jsonobj.impressions.length;
var impressionArr = [];
impressionArr = jsonobj.impressions;
payloads = [
{ topic: 'test', messages: impressionArr, partition: 0 }
];
producer.on('ready', function(){
producer.send(payloads, function(err, data){
console.log(data);
});
});
producer.on('error', function(err){
console.log("Error: "+err)
});
});
and my JAVA consumer is :
JavaInputDStream<String> messagesFrmSpecifiedOffset= KafkaUtils.createDirectStream(
sc,
String.class,
String.class,
StringDecoder.class,
StringDecoder.class,
String.class,
kafkaParams,
fromOffset,
new Function<MessageAndMetadata<String, String>, String>() {
public String call(MessageAndMetadata<String, String> msgAndMd) throws Exception {
return msgAndMd.message();
}
}
);
and I am getting impressions as separate messages as follows in JAVA consumer.
JavaDStream<Record> rdd_impressionRecords = messagesFrmSpecifiedOffset.map(
new Function<String, Record>() {
public Record call(String impressions) throws Exception {
System.out.println("impressions: " + impressions);
Record sd = new Record();
return sd;
}
});
BUT MY PROBLEM IS:
that I am getting output in object form like:
impressions: [object Object]
impressions: [object Object]
impressions: [object Object]
impressions: [object Object]
I know that I am sending JSON and recieving as String but anyone can help me to do solution in three ways:
1. Can I get key, values from [object Object] in Java class.
2. Is it possible to send each array element as String (using JSON.stringify) in NodeJS without any loop. Direct transfer as I am doing.
3. Can I rewrite method of createDirectStream that returns JSON obect directly.
In addition to Zdeněk Tisoň answer:
a) First use JSON.stringify() to create a string and send it over the net.
b) At the consumers side transform this string to whatever you want. If you want it to be Json you can use JSON.parse().
Client code could be:
var _ = require('lodash');
var payloads = _.map(JSON.parse(data).impressions, function(imp){
return JSON.stringify(imp);
});
producer.send(payloads, function(err, data){
});
Spark code could use json-simple library:
import org.json.simple.*;
JSONObject imp = (JSONObject) JSONValue.parse(impression);
String impressionId = (String) imp.get("impressionId");
You could use Java's JSONObject to get the string as a JSONObject like so:
JSONObject jsonObject = new JSONObject(impressions)
Then use the JSONObject functions to get what you need as listed here:
http://docs.oracle.com/javaee/7/api/javax/json/JsonObject.html
Use JSON.stringify before sending messages onto the Kafka bus. For example, your code changes to messages: JSON.stringify(impressionArr).
AFAIK producing object to kafka is not supported by kafka-node. If you try to do that, the object itself would be in format of [object Object], actually it's String '[object Object]'. That's why you can not de-serialize from Java.
try JSON.stringify(impressionArr) when produce in your node code and some JSON library when consume from Java side.

Categories

Resources