creating nested json file in node js - node.js

Here I want to create a nested json file. I have a variable loggedPerson1 as string which takes username of the person who have logged in and that person selects the courses. I want to create the json file in such a manner that registered courses would come under that name of that user.
var exists = fs.existsSync('RegisteredCourses.json');
if(exists) {
console.log("Loading");
var data = fs.readFileSync('RegisteredCourses.json', 'utf-8');
objRegister = JSON.parse(data);
}
else {
console.log('created new ')
var objRegister = {loggedPerson1:[]};
}
app.get('/RegisteredCourses',(req,res) =>{
res.send(loggedPerson)
})
app.post('/RegisteredCourses',(req,res) =>{
var declaredCourse =
{
key: Date.now().toString(),
CourseName : req.body.CourseName,
CourseCode: req.body.CourseCode,
StartDate:req.body.StartDate,
EndDate:req.body.EndDate,
Total_Fee: req.body.Fees,
Delivery_Mode : req.body.Delivery_Mode,
Description : req.body.Description,
CourseType: req.body.CourseType
}
if(!declaredCourse.CourseName ){
reply ={
msg:"Please enter data correctly"
}
res.send(reply)
}
else{
objRegister.loggedPerson1.push(declaredCourse)
let data = JSON.stringify(objRegister, null, 2);
fs.writeFile('RegisteredCourses.json',data,finished);
console.log('RegisteredCourses updated')
function finished(err){
reply = {
status:"Success",
}
res.send(reply)
console.log(reply)
}
}
})

It's not clear whether you're looking for the structure of the JSON here or something else. The JSON structure could be something like:
{
"students": {
"studentName": "Person 1",
"Courses": {
"one": "one",
"two": "two"
}
}
}
your code to read it out with:
var data = fs.readFileSync('RegisteredCourses.json', 'utf-8');
objRegister = JSON.parse(data);
should work fine, i've used the same in my projects.

Related

How to find text in json array

Im making a game and one of its functions is to join/create private rooms. Private rooms are generated randomly, but before generating a room, I want to try to be sure that the room id don't exists.
var rooms = {
'ROOM ID GENERATED RANDOMLY':
Room {
id: 'ROOM ID GENERATED RANDOMLY',
players: [],
gameState: 'WAITING',
currentCard: 'g:2',
currentPlayerIndex: NaN,
currentDirection: 1,
cardsStack: [] },
'ROOM ID GENERATED RANDOMLY':
Room {
id: 'ROOM ID GENERATED RANDOMLY',
players: [ [Player] ],
gameState: 'WAITING',
currentCard: 'g:2',
currentPlayerIndex: 0,
currentDirection: 1,
cardsStack: [] },
...
}
Already tried
var SEARCH = 'x';
for (var i=0; i < rooms.length; i++) {
console.log(rooms[i])
if (rooms[i].Room.id === SEARCH) {
return rooms[i];
}
}
Try this function
function roomIdIsUnique (newKey) {
var roomKeys = Object.keys(rooms);
for (const key of roomKeys) {
if (key === newKey) return false;
}
return true;
}
var rooms = { /* Room objects */ }
var newRoomKey = /* Generate new room key code */
if (roomIdIsUnique(newRoomKey)) {
/* Continue */
} else {
/* Do something else */
}
This question is pretty vague, but I'll do my best to answer it.
You can use Object.keys() to get an array containing the keys, and then run the Array#indexOf function on that array. It will return -1 if the key is not in the array, else it will return the index
var rooms = { "key1": { property: "123" }, "key2": { property: "abc" } }
if(Object.keys(rooms).indexOf(SEARCH) != -1) {
alert("Room id exists");
} else {
alert("Room does not exist");
}

Reload page content if database variable has changed Meteor

I am working on meteor app. I want to reload the content of the client when the database variable has changed. I am using pub-sub. I want to load content if the status variable has changed.
Meteor.publish('activities', function(loggedInUserToken) {
var authObj = AuthenticationToken.findOne({ authToken: loggedInUserToken });
if (authObj) {
var userObj = Users.findOne({ _id: authObj.user_id });
var activities = Activities.find({}, { sort: { createdAt: -1 } });
return activities;
}
return this.ready();
});
Template.masterSku.onCreated(function() {
var instance = this;
instance.autorun(function() {
var loggedInUserToken = "xxxxxxxxxxxxxxxx"
statusSuscription = instance.subscribe("activities", loggedInUserToken);
var activitiesObj = Activities.findOne({}, { sort: { createdAt: -1 } })
if (activitiesObj && activitiesObj.status == "true") {
console.log("Status Changed load Content accordingly")
}
})
The autorun will not recompute until a reactive data has changed AND this change is requested within the computation. While a subscription is a reactive source, you also need to check for it's readyness and thus cause a new computation cycle:
instance.autorun(function() {
var loggedInUserToken = "xxxxxxxxxxxxxxxx"
var statusSuscription = instance.subscribe("activities", loggedInUserToken);
if (statusSuscription.ready()) { // causes a new compuation by the Tracker
var activitiesObj = Activities.findOne({}, { sort: { createdAt: -1 } })
if (activitiesObj && activitiesObj.status == "true") {
console.log("Status Changed load Content accordingly")
// here you can insert data into a ReactiveVar or ReactiveDict and use
// result in a Template helper, which itself will cause your Template to re-render
}
}
}
You can use Tracker in onCreated function OR you can try fill data through helpers.
import { Tracker } from 'meteor/tracker';
Tracker.autorun(() => {
var loggedInUserToken = "xxxxxxxxxxxxxxxx"
statusSuscription = instance.subscribe("activities", loggedInUserToken);
var activitiesObj = Activities.findOne({}, { sort: { createdAt: -1 } })
if (activitiesObj && activitiesObj.status == "true") {
console.log("Status Changed load Content accordingly")
}
});

Sequelize create belongTo instance with reference

I'm using Sequelize for my new NodeJs project
I defined two models: BusinessUnit and Store with this association: Store.belongsTo(BusinessUnit);
module.test_data_insertion = function() {
models.BusinessUnit.findOne({
where: {
BUID: "001"
}
}).then(element => {
fs.readdirSync(dir).forEach(function(file) {
var contents = fs.readFileSync(dir + file);
var jsonContent = JSON.parse(contents);
models.Store.create({
StoreId: jsonContent.StoreId,
StoreName: jsonContent.StoreName,
businessUnitId: element.id
});
});
});
};
I don't find to right way to reference the element in my Store, I would like something like this where I don't have to reference an id field directly
module.test_data_insertion = function() {
models.BusinessUnit.findOne({
where: {
BUID: "001"
}
}).then(element => {
fs.readdirSync(dir).forEach(function(file) {
var contents = fs.readFileSync(dir + file);
var jsonContent = JSON.parse(contents);
models.Store.create({
StoreId: jsonContent.StoreId,
StoreName: jsonContent.StoreName,
businessUnit: element
});
});
});
};
It should be simple but I don't see it. Thanks
Assuming your association are setup correctly, you are looking for something like this:
module.test_data_insertion = function() {
models.BusinessUnit.findOne({
where: {
BUID: "001"
}
}).then(element => {
fs.readdirSync(dir).forEach(function(file) {
var contents = fs.readFileSync(dir + file);
var jsonContent = JSON.parse(contents);
element.setStore({
StoreId: jsonContent.StoreId,
StoreName: jsonContent.StoreName,
});
});
});
};
please read belongsTo from doc which enables a set method,
However please note if this is a one to many relationship(one business unit with many stores) you may need to switch to belongsToMany it has add method. because setStore would override previous set.
Also, i'm not sure if any of those method would work inside .forEach correctly since they are promise, you may need to switch to a traditional for loop.

parse dirty object is not working after migration

I have a question regarding parse cloud code. The following cloud code was working before migration written in cloud code but after migration its not returning desired output.
var streamClass = Parse.Object.extend("Streams");
streamObj = new streamClass({
objectId: "dummy",
streamerId: usersArr[i]
});
streamObj.dirty = function() {return false;};
There are two entities i.e. streams and users. Every user has streams. So there is users pointer(streamerId) in stream table. If user do not have any stream created then i am creating a stream dummy object and setting user(streamerId) as a pointer in stream object. When this code was called as a API, it was returning stream dummy object with user(streamerId) information before parse server migration. After migration the above code gives the following output.
{
"result": [
{
"__type": "Pointer",
"className": "Streams",
"objectId": "dummy"
}
]
}
It can noticed that there is no user(streamerId) information in the output. Can anyone please help me in this regard.
I am not saving this streamObj. I am returning this streamObj to IOS app. I also tested it through postman in google chrome. The following is a complete function which takes array of users object and array of streams objects and return one object contains user and its related streams.
function getUsersAndRecentStreams(usersArr, streamsArr) {
var responseObj = [];
var moment = require('moment');
var now = moment();
var currentDate = new Date();
for( var i=0; i<usersArr.length; i++ ) {
var streamObj = null;
for( j=0; j<streamsArr.length; j++ ) {
var streamerObj = streamsArr[j].get('streamerId');
if( streamerObj.id === usersArr[i].id ) {
if( moment(streamsArr[j].get('showTimeStart')) <= now && moment(streamsArr[j].get('showTimeEnd')) >= now ) {
streamObj = streamsArr[j];
break;
}
if( streamObj == null) {
streamObj = streamsArr[j];
}
else {
if( moment(streamsArr[j].get('showTimeStart')) <= now ) {
streamObj = streamsArr[j];
}
}
}
}
if( streamObj == null ) {
var streamClass = Parse.Object.extend("Streams");
streamObj = new streamClass({
objectId: "dummy",
streamerId: usersArr[i]
});
streamObj.dirty = function() {return false;};
var streamObj = new streamObj();
}
responseObj.push(streamObj);
}
return responseObj;
}
There are two cases.
1) When streamObj is not null. In this case the output is correct.
2) The second case when streamObj is null. In this case the following output is return which is not desired.
{
"result": [
{
"__type": "Pointer",
"className": "Streams",
"objectId": "dummy"
}
]
}
When streamObj is null, The following desired output should return this function.
{
"result": [
{
"__type": "Pointer",
"className": "Streams",
"objectId": "dummy",
"StreamerId": userObject
}
]
}

Meteor, MongoDb: Double inserting to collection on few occurences

I noticed this strange behaviour, when for few users only on production, it inserts every item multiple times to collection on asynchronous Meteor call. I tried multiple things, but nothing worked. I can't test on localhost, bc it never happens to me on localhost or in production.
I spent the whole night solving this, but didn't find any solution. I suppose it's caused by new Date(), but I have to call it somewhere. The production server is in Amsterdam and it seems like it happens only for users located further outside of Europe.
I found this to be similar issue, but can't really wrap my head on how to implement - https://github.com/meteor/meteor/issues/4263
Slug is what same songs are supposed to have the same.
This is the workflow, user clicks on song that triggers addNewSong function:
addNewSong = function (track) {
Globals.current_track = track;
checkIfSongAlreadySaved();
}
I need to check if song is already in collection, if it's -> route to it, else create the new song and route to it.
checkIfSongAlreadySaved = function() {
loadPrimaryGlobalItems();
Meteor.call('checkIfSongAlreadySaved', Globals.current_song_item_slug, function(error, result) {
if( result.item ) {
Globals.current_song_item_id = result.item._id;
Globals.current_song_item_slug = result.item.slug;
routeToSongPage();
if (! (result.item.download && result.item.mp3) ) {
downloadSong();
}
}
else {
loadSecondaryGlobalItems();
var item = {
slug:Globals.current_song_item_slug,
duration:Globals.current_duration,
thumbnail:Globals.current_song_thumbnail,
title:Globals.current_cleaned_song,
album:Globals.current_track.album,
artist:Globals.current_track.artists[0],
track:Globals.current_track.name,
date:result.date,
}
Globals.current_song_item_id = Songs.insert(item);
routeToSongPage();
downloadSong();
recentSongItem(result.date);
}
});
}
Add recent song
recentSongItem = function (date) {
Recentsongs.insert({
slug:Globals.current_song_item_slug,
songId:Globals.current_song_item_id,
title:Globals.current_cleaned_song,
duration:Globals.current_duration,
date:date,
});
}
If creating new song,
downloadSong = function() {
Meteor.call('findSong', Globals.current_song, function(error, result) {
console.log(result);
if (result) {
Globals.current_song_mp3 = true;
updateSongItemDownload(result.itemDetails);
}
else {
alert('not found')
}
});
}
and update song, to add download and mp3 values.
updateSongItemDownload = function(link) {
Songs.update({
_id: Globals.current_song_item_id
},
{
$set: {
download: link,
mp3: Globals.current_song_mp3,
}
});
}
Server methods:
Meteor.methods({
checkIfSongAlreadySaved: function(slug) {
return {item: Songs.findOne({slug:slug}), date: new Date()};
},
findSong:function(song) {
ServerGlobals.current_song = song;
var result = searchSite();
return result;
},
});
EDIT:
This is my subscription, just in case it might be causing the problem:
Template.songPage.onCreated(function() {
Session.set('processing', true);
var self = this;
self.autorun(function() {
var id = Router.current().params.id;
self.subscribe('singleSong', id);
var item = Songs.findOne({_id: id});
if (item) {
if (item.download) {
createSong(item.download);
}
else if( item.download === false ) {
console.log('item not found');
}
Session.set('loader', false);
Session.set('processing', false);
}
});
});
Meteor.publish('singleSong', function(id) {
check(id, String);
return Songs.find({_id: id});
});
You can apply a unique index on the slug field to ensure the same slug can only exist once and the second operation to insert will fail and show up as an error in your callback which you can discard or alert user as you desire.
db.collection.createIndex( { slug: 1 }, { unique: true } )
You will need to clear or modify the slug name on the dups from the db before applying the index though

Resources