Add data to existing json object - javascript

So what i'm trying to achieve is creating a json flat file to store user info where i'm stuck is that i don't know how to add new nested objects that are empty and then save the json file and reload it.
what i have in my *json* file is this.
{
"users" : {
"test" : {
},
"test1" : {
}
}
}
I'm trying to add as many new objects as i want to it. So for example.
{
"users" : {
"test" : {
},
"test1" : {
},
"test2" : {
},
"test3" : {
}
}
}
My server side Javascript
json.users.push = username;
fs.writeFile("./storage.json", JSON.stringify(json, null, 4) , 'utf-8');
delete require.cache[require.resolve('./storage.json')];
json = require("./storage.json");
With this code it does not write the file so when the require is done i end up with the same file and my json object ends up like this when i console.log it
{
"users": {
"test": {},
"test1": {},
"push": "test2"
}
}
Please do not recommend some external module to solve something has simple as this. Also if any one can point me to a in depth json documentation that gets straight to the point with what i'm try to do it would be appreciated

Use [] to access a dynamic key on the object
json.users[username] = {a: 1, b: 2}
Be careful naming your variable like that tho because json the way you're using it is not JSON. JSON is a string, not an object with keys.
See the below demo for distinction
var json = '{"users":{"test1":{},"test2":{}}}';
var obj = JSON.parse(json);
var newuser = 'test3';
obj.users[newuser] = {};
console.log(JSON.stringify(obj));
//=> {"users":{"test1":{},"test2":{},"test3":{}}}

Related

Saving array and objects within said array

I am trying to make a simple to do app using vue.js, I want to try and save my to-dos that are set in the array so that when I reset the site, they still remain. Looking through some of the documentation I arrived at this:
data() {
return {
array: [
{id: 1, label: 'learn vuejs'},
]
}
},
methods: {
persist() {
localStorage.array = this.array;
alert('items saved')
}
},
mounted() {
if (localStorage.array && localStorage.array.id) {
this.array = localStorage.array;
this.array[id] = localStorage.array.id;
}
},
while this does save my array to localStorage, IT DOES NOT THE OBJECTS WITHIN. When I check localStorage in the console it shows :
array: "[object Object]"
anyone knows how to save the items within the array? if you do please explain it to me.
You need to store them as string. So localStorage.array = JSON.stringify(this.array), and when fetching from localStorage this.array = JSON.parse(localStorage.array);

How do I find a JSON value with a specific ID?

I have an object and I’m trying to find a specific value using an ID in ECMAScript6.
I’ve tried something like this: myvalue = this.json.find(x => x == '1234');
The JSON looks something like this:
{
"results": [
{
"abcde1234": {
"value": 4
}
},
{
"zxcv4567": {
"value": 2
}
}
]
}
All the examples I’ve found can only find off named key-value pairs.
Try
json.results.find(x => /1234/.test(Object.keys(x)[0]));
json = {
"results": [
{
"abcde1234": {
"value": 4
}
},
{
"zxcv4567": {
"value": 2
}
}
]
}
let r = json.results.find(x => /1234/.test(Object.keys(x)[0]));
console.log(r);
const json = {
'1234': { 'value' : 4},
'5678': { 'value' : 10}
};
const value = json['1234'];
console.log(value);
The JSON data doesn't seem proper.
But in case you are finding by key, you can directly access this, something like:
Parsed JSON maps directly to JavaScript types: Object, Array, boolean, string, number, null. Your example used find() which is (normally) a method used with arrays. If your JSON was structured like this, you could expect to use find:
const jsonString = '["a", "b", "c"]';
const jsonData = JSON.parse(jsonString);
jsonData.find(x => x === "a"); // "a"
But it seems like your data is structured as an object, so you can use normal property access:
const jsonString = '{"1234": {"value": 4}, "5678": {"value": 10}}';
const jsonData = JSON.parse(jsonString);
jsonData["1234"] // {value: 4}
jsonData["1234"].value // 4
EDIT
OP changed the data example, so the above code is less directly applicable, but the general point is: once you parse it, it's just javascript.

access array member of type object in javascript

I have been trying to access array member from an Array (data_array).My variable data_array is part of json something similar to code below. The code below is not the actual code. The actual code is coming in play when i am trying to create a React component. I can paste the complete React component but it would contain some unnecessary information. So i thought i would add some mock example. Apologies if it misled people. Currently i was hoping to get some hints on what could possibly go wrong in such scenario?
:
data: {
"name": "Arjun",
"records" : [
{
"value": 3
},
{
"value": 6
},
{
"value":7
}
]
}
var data_array = data.records
console.log(data_array) -> Array[3]
console.log(data_array[0]) -> It displays Uncaught TypeError: Cannot read property '0' of undefined
console.log(typeof data_array) -> Object.
What's confusing to me is my first output as it says its an Array.I am fairly new to javascript. So maybe i am missing something. Any help would be appreciated.
Edit: This would still be missing a nested React Component but it would be of no use in this case. I am calling the nested component Foo for now
var React = require('react'),
Router = require('react-router'),
mui = require('material-ui'),
Foo = require('./foo.jsx');
var TempReact = React.createClass({
mixins: [Router.Navigation],
getInitialState: function() {
return {
data: {}
};
},
componentDidMount: function() {
// Do a web request here to actually get the data from the backend API
// this.setState({
// });
// For now, load our fake data
this._loadFakeData();
},
render: function() {
//console.log(this.state.data)
for(var record in this.state.data.records) {
console.log(record.Value);
}
//console.log(this.state.data["records"][0]["Value"])
return (
<div>
<p>^ That will still say , since the header up there is decided by temp-page.jsx, which is
based on the route</p>
<br/>
<p>We've loaded the fake data into our component's state, and here's proof:</p>
{this.state.data.name}
<br/>
<br/>
<Foo name={["temp1",this.state.data.records,"green"]}/>
</div>
);
},
_loadFakeData: function() {
this.setState({
data: {
"name": "Arjun",
"records" : [
{
"Value": 6
},
{
"Value": 7
},
{
"Value": 8
}
]
}
});
}
});
module.exports = TempReact;
Arrays are typeof Object. They're just an object with some fancy stuff going on.
The following example works:
var data = {
"name": "Arjun",
"records" : [
{
"value": 3
},
{
"value": 6
},
{
"value":7
}
]
}
var data_array = data.records
console.log(data_array[0]) // Object {value: 3}
This error happens when you do something like this:
var data = {};
var data_array = data.array; // data.array is undefined and subsequently data_array.
console.log(data_array[0]); // Throws: Uncaught TypeError: Cannot read property '0' of undefined
You're not far off lets say you store this object in a variable called jsonData just for an example :
var jsonData = {
data: {
"name": "Arjun",
"records" : [
{
"value": 3
},
{
"value": 6
},
{
"value":7
}
]
}
}
You'll need to access the variable > property > nested property , then specify the index like so :
var data_array = jsonData.data;
console.log(data_array.records[0].value)
--> should log 3
EXAMPLE HERE: http://codepen.io/theConstructor/pen/wGdpjq
So the problem might have been with SetState() in React, I was able to access the objects by pushing them first in an empty array:
var varArr = new Array();
for(key in this.state.data.records) {
if(this.state.data.records.hasOwnProperty(key)) {
var value = this.state.data.records[key];
varArr.push(value);
}
}
data_array is an Array. data.records in an Array. What are you expecting to see?

Storing nested javascript objects in redis - NodeJS

I recently switched from memcached to redis in nodejs. The thing I liked in node-memcached was that I can save the whole javascript object in the memory. Sadly I couldn't do this in redis. For example, I got the following object:
var obj = {
name: "Hello world!",
author: "admin",
user: {
"yolololo" : {
"id": "352asdsafaseww",
"server": 5,
"data" : {
x: 1,
y: 1,
z: 50
}
},
"yolol" : {
"id": "358dsa",
"server": 7
}
}
}
with the 3rd-Eden/node-memcached I could just do:
memcached.set("obj", obj, 12345, function(err) { });
and then
memcached.get("obj", function(err, data) {
console.log(data);
});
And I'll get the object I saved, just the way it is.
The problem with redis is that if I save the object like this:
redisclient.set("obj", obj, redis.print);
When I get the value with
redisclient.get("obj", function(err, data) {
console.log(data);
});
The output is just string containing [object Object].
Yeah I understand redis is text-based protocol and it's trying to do obj.toString(), but seems memcached take care of objects and redis don't.
I thought I could just do:
redisClient.set("obj", JSON.stringify(obj));
but I'm not sure if this will be good, because there will be insane high I/O and I'm not sure if the JSON obj->string will be bottleneck ( 10k+ request/second ).
Both Memcached and Redis store the data as string, but does redis have built-in feature for converting objects?
First of all redis only supports the following data types:
String
List
Set
Hash
Sorted set
You'll need to store objects as string in both redis and memcached.
node-memcached parses/stringifies the data automatically. But node-redis doesn't.
However, you can implement your own serialization/deserialization functions for your app.
The way node-memcached stringifies an object is as follows:
if (Buffer.isBuffer(value)) {
flag = FLAG_BINARY;
value = value.toString('binary');
} else if (valuetype === 'number') {
flag = FLAG_NUMERIC;
value = value.toString();
} else if (valuetype !== 'string') {
flag = FLAG_JSON;
value = JSON.stringify(value);
}
It also parses the retrieved text this way:
switch (flag) {
case FLAG_JSON:
dataSet = JSON.parse(dataSet);
break;
case FLAG_NUMERIC:
dataSet = +dataSet;
break;
case FLAG_BINARY:
tmp = new Buffer(dataSet.length);
tmp.write(dataSet, 0, 'binary');
dataSet = tmp;
break;
}

Create a empty JSON object from an existing JSON object array

I have a JSON object with two arrays of an object x.
I'm using angularJS and I want to add/edit/delete objects in the JSON (just like the Angular TODO app example on angular.org).
Is there a way to create a new empty (with the structure of x but no values) JSON object of x, and simply push that to the above JSON object array?
How do I go about creating an empty value JSON object of x?
My Sample object x is (I nullified all the values) pasted below. So my JSON is just an array of these objects. In Angular, I want the user to fill out a form and hold the data in an empty object of this type and push it to the array. That's my goal.
Sample JSON
[{
"id": null,
"title": "",
"date": {},
"billPayerId": null,
"notes": "Sample Notes",
"billFinances": {
"billPayerId": null,
"billItemEntry": [
{
"itemDescriptionId": 1,
"itemDescription": "",
"userIdAndLiableCost": [
{
"userId": null,
"liableCost": null
},
{
"userId": null,
"liableCost": null
}
]
},
{
"itemDescriptionId": null,
"itemDescription": "",
"userIdAndLiableCost": [
{
"userId": null,
"liableCost": null
},
{
"userId": null,
"liableCost": null
}
]
}
],
"billTotal": null
},
"groupId": null
}];
You can use an object literal to store whatever you want. It is just a bag of properties (i.e. name) and values. e.g. var order = {};
Then an array literal could be used to hold the orders. e.g var orders = []; orders.push(order); But it would be just as easy to use another object literal with the id as a property.
But it seems like you want some sort of validation. Perhaps something to manage the order data and handle the validation, etc. Like so:
orderManager.dataStore = {
_data: {},
//_redundantData = []; //could easily store in an array if id isn't unique
get: function (id) {
return this._data[id];
},
getAll: function () {
return this._data;
},
set: function (id, order) {
validateOrder(order);
this._data[id] = order;
},
clear: function (id) {
this._data[id] = undefined;
},
add: function (order) {
validateOrder(order);
this._data[order.id] = order;
},
assertNotNull: function (data, key) {
if(data[key] == undefined) {
throw new Error("Key Missing: " + key + " for " + data.name);
}
},
validateOrder: function(order) {
assertNotNull(order,"id");
assertNotNull(order,"title");
//etc
},
containsOrder: function (id) {
for(var i=0;i<array.length;i++) {
if(array[i].id === id) {
return true;
}
}
return false;
}
};
If I'm reading all of this right, I think you may be misunderstanding how Angular works. You don't have to create an empty object for Angular to use within a form. As long as your form's inputs use dot notation, it will generate the object for you as the user fills in the inputs with data.
E.g.
<form>
<input type="text" ng-model="myForm.name">
<input type="text" ng-model="myForm.email">
<input type="text" ng-model="myForm.nickname">
</form>
Since we used the dot notation in the ng-model attribute, it creates the object for us as the user fills out the form. The generated object would look like this after the inputs are completed:
$scope.myForm = {
name: 'Justin',
email: 'justin#email.com',
nickname: 'Cerebrl'
};
Now, normally once the user clicks save, you'd send the data to the server for persistence and you could then just empty the object (e.g. $scope.myForm = {};) to reset the form. But, for some reason, you want to build an array first, then send the whole thing to the server when fully complete (at least that's how I'm understanding it).
To do this, you have to get around the fact that Objects and Arrays in JavaScript are reference types, so you can't push the object full of data to an array, and then empty the object to reset the form as that would then empty the object within the array as well, blowing your data store.
I would personally address this problem with Angular's object copy method (e.g. angular.copy(source);) seen here: http://docs.angularjs.org/api/angular.copy This allows you to make a non-referenced copy of an object and use it without mutating the original object. So, within the "save function", you would have this:
var myNewObj = angular.copy($scope.myForm);
myDataArray.push(myNewObj);
$scope.myForm = {};
That way, you've saved the completed form data, pushed it to the array and cleared the form's input data. Does this answer your question?

Categories