Im working with a module known as update-json. Im attempting to update json within a file, im having issues addressing the key I want or what seems to happen is a new entry gets added in a different branch..
My Querykeys.json looks like this
{
"servers": [
{
"netdomain": "google.com",
"netshare": "password",
"authip": "216.58.203.46"
},
{
"netdomain": "localhost",
"netshare": "localghost",
"authip": "127.0.0.1"
},
{
"netdomain": "facebook.com",
"netshare": "timeline",
"authip": "31.13.69.228"
}
]
}
Currently I have the system reading and isolating code just fine, my intenetions are to update a netshare from the code of localhost from localghost to "foo".
The module in question is located here, https://www.npmjs.com/package/update-json.
The code i have setup is exactly like there code is on the website.
var updateJson = require('update-json');
// let's assume the file contains this:
// {aaa: 'bbb', ccc: 'ddd'}
var file_path = './querykeys.json';
var data = {servers: 'xxx', yyy: 'zzz'};
updateJson(file_path, data, function (error) {
if (error) {
throw error;
}
else {
console.log();
}
});
With the type of structure that I have, how can i format var data to independently change localhosts netshare to foo?
Thank you
Related
I'm doing a basic 'Visitor Book' function.
Users can submit a little form (with three inputs : name, msg and emoji).
I grab it with req.body in my router component. I'm using nodejs, with express and bodyparser.
I only want to store this data in a JSON, don't want any database involved here.
I'm in trouble with the writeFile method, using 'fs' module.
It work but it push the new data outside the single-array of my JSON file.
Do you know if I can push in inside the array ? Like a .push method, but with writeFile/appendFile/wathever that works good with json files.
Here is my code :
app.post (router) :
app.post('/visitorBook', async (req, res) => {
let formData = {
name: req.body.name,
msg: req.body.msg,
emoji: req.body.emoji
}
try {
console.log(req.body)
let data = JSON.stringify(formData, null, 2);
fs.writeFile("./views/scripts/dataVisitorBook.json", data, { { // dataVisitorBook.json is the storage file
flag:'a' // this flag specify 'please append it' over 'please override file'
}
}, (err) => {
console.log('error :', err)
});
res.redirect('/contact')
} catch (error) {
console.error('/visitorBook route error : ', error)
}
})
My JSON :
[
{
"name": "test1",
"msg": "test1",
"emoji": "<i class='fas fa-hippo fa-3x'></i>"
},
{
"name": "test2",
"msg": "test2",
"emoji": "<i class='fas fa-hippo fa-3x'></i>"
}
]
{
"name": "sd",
"msg": "sd",
"emoji": "<i class='fas fa-kiwi-bird fa-3x'></i>"
}
So the last one with "sd" in name and msg is the pushed one. The 2 other are manually written by me, for readFile tests.
I hope I provided all the information needed. Not used to post here...
Thanks you.
If you read from the existing file and parse it with JSON.parse, you will be able to actually use Array.push on it. And then you can write the stringified result back into the file:
fs.readFile("./views/scripts/dataVisitorBook.json", function (err, data) {
if (err) throw err;
let data = JSON.parse(data.toString('utf8'));
data = JSON.stringify(data, null, 2);
fs.writeFile("./views/scripts/dataVisitorBook.json", data, { { // dataVisitorBook.json is the storage file
flag:'a' // this flag specify 'please append it' over 'please override file'
}
}, (err) => {
console.log('error :', err)
});
})
It might not be optimal though as it is likely to take more time as the file grows bigger.
I appreciate your simple try But using some standards can be much better to you
There are some Standard JSON DBs for Node like :
Simple JSON DB
Node JSON DB
Also, you can try SQLite
I also try with a simple JSON file of use as DB. I faced lots of work and I have managed it too. So my advice is to use some standard libraries
Apart from it, you have to get the file data Parse it as JSON (Decoding) make changes and again serialize it and write into a file (Encoding).
[SOLVED]
Thanks to #Divarrek , I've archieved to make it work.
So :
Read the file with fs.readFileSync.
Then, I store this rawdata in a variable, while parsing it to JSON.
THen, I push it in the 'jsonBook' variable which is the json file temporarly made into a simple object-variable.
Then I write in the file with writeFile, passing the data as variable 'parsed', which contain a JSON.stringified version of my 'jsonBook'
app.post("/visitorBook", async (req, res) => {
let formData = {
name: req.body.name,
msg: req.body.msg,
emoji: req.body.emoji,
};
try {
let rawdata = fs.readFileSync("./views/scripts/dataVisitorBook.json");
var jsonBook = JSON.parse(rawdata);
let formDataParsed = JSON.stringify(formData, null, 2);
jsonBook.push(formData);
let parsed = JSON.stringify(jsonBook, null, 2);
fs.writeFile("./views/scripts/dataVisitorBook.json", parsed, (err) => {
if (err) throw err;
console.log("saved");
});
res.redirect("/contact");
} catch (error) {
console.error("/visitorBook route error : ", error);
}
});
I hope I was clear. Maybe I did some explanation error, I'm trying my best.
I am currently using PouchDB as my DB and I am using Cloudant for the remote service. I am currently trying to create document, however, when I invoke the function, I have errors.
May I know where did I do wrong? Could it be the URL wrong or my syntax is wrong?
Uncaught Reference Error: PouchDB is not a constructor
This is my javascript code
function pouchdb() {
var db = new PouchDB("todos");
var remoteDB = new PouchDB("http://example.cloudant.com/example");
window.PouchDB = db;
var doc = {
"_id": "Can123",
"name": "You123",
"occupation": "See1",
"age": 3,
"hobbies": [
"Watch 9pm show",
"chasing laser pointers",
"lookin' hella cute"
]
};
db.put(doc);
PouchDB.sync(db, remoteDB);
}
HTML code
<button onclick="pouchdb()">pouchdb</button>
Update
I changed my insert code for this set of code
function pouchdb() {
var db = new PouchDB("todos");
var remoteDB = new PouchDB("http://example.cloudant.com/example");
var todo = {
_id: "mittens1233",
title: "hello",
occupation: "kitten123"
};
db.put(todo, function callback(err, result) {
if (!err) {
console.log('Successfully posted a todo!');
}
});
}
The result i got back is Successfully posted a todo!, however, my cloudant dashboard still shows 0 doc. May I know why?
Remove that line
window.PouchDB = db;
I think that's the problem. Once you click the button, the global PouchDB turns the variable db, what makes it not be a constructor anymore.
If the error still continues, #gcampbell comment should be right?
I am communicating to a web service using nodejs and node-soap. But i just can't seem to get the syntax right for passing the parameters to the service.
The documentation says i need to send an array with the field uuid and its value.
Here is the Php code i got as an example from the web service owner
$uuid = "xxxx";
$param = array("uuid"=>new SoapVar($uuid,
XSD_STRING,
"string", "http://www.w3.org/2001/XMLSchema")
)
and here is the code i am using in my node server
function getSoapResponse()
{
var soap = require('soap');
var url = 'http://live.pagoagil.net/soapserver?wsdl';
var auth = [{'uuid': 'XXXXXXXXX'}];
soap.createClient(url, function(err, client) {
client.ListaBancosPSE(auth, function(err, result)
{
console.log(result);
console.log(err);
});
});
With this i get bad xml error
var auth = [{'uuid': 'XXXXXXXXX'}];
or
var auth = [["uuid",key1],XSD_STRING,"string","http://www.w3.org/2001/XMLSchema"];
and with this i get the response "the user id is empty" (the uuid)
var auth = {'uuid': 'XXXXXXXXX'};
Any suggestions?
Finally using the content in this answer and modifying the code in the soap-node module i was able to obtain the code i needed.
I needed something like this:
<auth xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">uuid</key>
<value xsi:type="xsd:string">{XXXXXX}</value>
</item>
</auth>
so I used this for creating the parameters:
var arrayToSend=
{auth :
[
{ 'attributes' : {'xsi:type':"ns2:Map"},
'item':
[
{'key' :
{'attributes' :
{ 'xsi:type': 'xsd:string'},
$value: 'uuid'
}
},
{'value' :
{'attributes' :
{ 'xsi:type': 'xsd:string'},
$value: uuid
}
}
]
}
]
};
and sent it like this:
soap.createClient(url, myFunction);
function myFunction(err, client)
{
client.ListaBancosPSE(arrayToSend,function(err, result)
{
console.log('\n' + result);
});
}
Then the tricky part was modyfing the wsd.js so it didn't add a extra tag everytime i used and array. I went to line 1584 and changed the if for this:
if (Array.isArray(obj))
{
var arrayAttr = self.processAttributes(obj[0]),
correctOuterNamespace = parentNamespace || ns; //using the parent namespace if given
parts.push(['<', correctOuterNamespace, name, arrayAttr, xmlnsAttrib, '>'].join(''));
for (var i = 0, item; item = obj[i]; i++)
{
parts.push(self.objectToXML(item, name, namespace, xmlns, false, null, parameterTypeObject, ancXmlns));
}
parts.push(['</', correctOuterNamespace, name, '>'].join(''));
}
basically now it does not push the open and close tag in every iterarion but instead only before and after the whole cycle.
Also i needed to add the definitions for the xlmns of the message. Client.js:186
xml = "<soap:Envelope " +
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
'xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
'xmlns:ns2="http://xml.apache.org/xml-soap"' +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
Hopefully this could be of help for people using this library and being in this situation.
There is not much I can do for you but here are a few tips to get you started.
Use client.describe() to see how the service expects the arguments.
The service you are trying to reach has the following structure:
{ App_SoapService:
{ App_SoapPort:
{ Autorizar: [Object],
AutorizarAdvance: [Object],
AutorizarIac: [Object],
ListaBancosPSE: [Object],
AutorizarPSE: [Object],
AutorizarTuya: [Object],
AutorizarBotonCredibanco: [Object],
FinalizarPSE: [Object],
FinalizarTuya: [Object],
ConsultarReferencia: [Object] } } }
Taking a closer look to the specific method ListaBancosPSE it provides this info:
{input: { auth: 'soap-enc:Array' },
output: { return: 'soap-enc:Array' }}
I tried with this:
var soap = require('soap');
function getSoapResponse(url, auth) {
soap.createClient(url, function(err, client) {
console.log(client.describe());
console.log(client.describe().App_SoapService.App_SoapPort.ListaBancosPSE);
client.ListaBancosPSE(auth, function(err, result) {
console.log(JSON.stringify(result));
console.log(err);
});
});
}
getSoapResponse('http://live.pagoagil.net/soapserver?wsdl', {'soap-enc:Array' : {'uuid': 'XXXXXXXXX'}});
The response is the same "Negada, Error nombre de usuario vacio, No se pudo autenticar en pagoagil.net.".
The next steps for you would be to determine which is the message the service is expecting.
Could be something like:
<tns:ListaBancosPSE><uuid>XXXXXXXXX</uuid></tns:ListaBancosPSE>
Or
<tns:ListaBancosPSE><soap-enc:Array><uuid>XXXXXXXXX</uuid></soap-enc:Array></tns:ListaBancosPSE>
Once you know that, you just have to add a console.log in the node-soap package you installed, so go to where you have your node_modules installed and open the file
node_modules/soap/lib/client.js
Add a console.log at line 187, right after the message has been set and
console.log("Message! ", message);
This will show the message, that should give you enough information to figure out the format of the arguments.
Already a few years gone by, but I have another suggestion to solve this problem.
If you (like me) don't come along with all the namespace stuff (due to a lack of understanding), you can directly put serialized XML strings into a value like this:
var objToSend = {
someString: 'stringVal',
arrayContent: {
$xml: '<item>val1</item><item>val2</item>'
}
}
I am attempting to get a list out of my database. The documents look like:
{
"class": "lists",
"collection": "symptoms",
"order": "6",
"en": "Headache",
"_id": "9022034e7d5ecd0efab0762c5b7f0c04"
}
There are an arbitrary number of "collection"s.
A view function simply returns a bunch of objects in the class "lists":
// Emit lists
exports.viewlist = {
map: function(doc) {
if (doc.class === 'lists') {
emit(
doc.collection, {
order: doc.order,
name: doc.en
});
}
}
};
I wrote a list function to try to filter the output to just the list that I want.
exports.viewlist = function(head, req) {
var row;
start({
code: 200,
headers: {
'Content-Type': 'text/json; charset=utf-8',
}
});
while (row = getRow()) {
if (row.collection === req.l) {
send(JSON.stringify(row.value));
}
}
};
CouchDB throws an error when I visit the URL of the list:
http://localhost:5984/dev/_design/emr/_list/viewlists/viewlist?l=symptoms
{"error":"TypeError","reason":"{[{<<\"message\">>,<<\"point is undefined\">>},
{<<\"fileName\">>,<<\"/usr/share/couchdb/server/main.js\">>},
{<<\"lineNumber\">>,1500},\n {<<\"stack\">>,
<<\"(\\\"_design/emr\\\",[object Array],
[object Array])#/usr/share/couchdb/server/main.js:1500\
()#/usr/share/couchdb/server/main.js:1562\
#/usr/share/couchdb/server/main.js:1573\
\">>}]}"}
I can't figure out where I'm going wrong here.
I also ran into this error and what causes it, as hinted at by #Pea-pod here Submitting form to couchDB through update handler not working, is not defining properly your exports in the couchapp's design documents. In our case it was as list function that couldn't be called and instead displayed a 500 error with Type error and point is undefined in the couchdb log.
We use kanso and in the app.js we hadn't required the list file. We had:
module.exports = {
rewrites: require('./rewrites'),
views: require('./views'),
shows: require('./shows')
};
Changing it to the following solved the problem:
module.exports = {
rewrites: require('./rewrites'),
views: require('./views'),
shows: require('./shows')
lists: require('./lists'),
};
Can I suggest to a moderator to change the title of this question to include point is undefined which is the error that shows up in the CouchDB log when this type of error is made, in order to help others find it more easily?
The problem may be with the actual client, but he's not responding on github, so I'll give this a shot!
I'm trying to post, in the body, nested JSON:
{
"rowkeys":[
{
"rowkey":"rk",
"columns":[
{
"columnname":"cn",
"columnvalue":"{\"date\":\"2011-06-21T00:53:10.309Z\",\"disk0\":{\"kbt\":31.55,\"tps\":6,\"mbs\":0.17},\"cpu\":{\"us\":5,\"sy\":4,\"id\":90},\"load_average\":{\"m1\":0.85,\"m5\":0.86,\"m15\":0.78}}",
"ttl":10000
},
{
"columnname":"cn",
"columnvalue":"cv",
"ttl":10000
}
]
},
{
"rowkey":"rk",
"columns":[
{
"columnname":"cn",
"columnvalue":"fd"
},
{
"columnname":"cn",
"columnvalue":"cv"
}
]
}
]
}
When I remove the columnvalue's json string, the POST works. Maybe there's something I'm missing regarding escaping? I've tried a few built in escape utilities to no avail.
var jsonString='the json string above here';
var sys = require('sys'),
rest = require('fermata'), // https://github.com/andyet/fermata
stack = require('long-stack-traces');
var token = ''; // Username
var accountId = ''; // Password
var api = rest.api({
url : 'http://url/v0.1/',
user : token,
password : accountId
});
var postParams = {
body: jsonString
};
(api(postParams)).post(function (error, result) {
if (error)
sys.puts(error);
sys.puts(result);
});
The API I'm posting to can't deserialize this.
{
"rowkeys":[
{
"rowkey":"rk",
"columns":[
{
"columnname":"cn",
"columnvalue":{
"date":"2011-06-21T00:53:10.309Z",
"disk0":{
"kbt":31.55,
"tps":6,
"mbs":0.17
},
"cpu":{
"us":5,
"sy":4,
"id":90
},
"load_average":{
"m1":0.85,
"m5":0.86,
"m15":0.78
}
},
"ttl":10000
},
{
"columnname":"cn",
"columnvalue":"cv",
"ttl":10000
}
]
},
{
"rowkey":"rk",
"columns":[
{
"columnname":"cn",
"columnvalue":"fd"
},
{
"columnname":"cn",
"columnvalue":"cv"
}
]
}
]
}
Dual problems occuring at the same occurred led me to find an issue with the fermata library handling large JSON posts. The JSON above is just fine!
I think the real problem here is that you are trying to post data via a URL parameter instead of via the request body.
You are using Fermata like this:
path = fermata.api({url:"http://example.com/path");
data = {key1:"value1", key2:"value2"};
path(data).post(callback);
What path(data) represents is still a URL, with data showing up in the query part. So your code is posting to "http://example.com/path/endpoint?key1=value1&key2=value2" with an empty body.
Since your data is large, I'm not surprised if your web server would look at such a long URL and send back a 400 instead. Assuming your API can also handle JSON data in the POST body, a better way to send a large amount of data would be to use Fermata like this instead:
path = fermata.api({url:"http://example.com/path");
data = {key1:"value1", key2:"value2"};
path.post(data, callback);
This will post your data as a JSON string to "http://example.com/path" and you would be a lot less likely to run into data size problems.
Hope this helps! The "magic" of Fermata is that unless you pass a callback function, you are getting local URL representations, instead of calling HTTP functions on them.