How to change the value of a JSON file using arithmetics?

Viewed 116

Sorry if the title doesn't make sense.

Basically, in my case.JSON file I have the following:

{
  "case": 0
}

I want it so that when the code is ran case goes up by 1 in value, and I can assign that anywhere so (discord.js example) in a Rich-embed I can put the caseNumber at the footer/field/description.

I had a hard time trying to have this make sense so any help would be appreciated.

I want to use Node FS to save it to my JSON file every time I restart my code So I want it to update it everytime.

These are my previous attempts:

// console.log('Starting...')
var fs = require('fs');
var cases = fs.readFileSync('case.json');
var caseUp = cases + 1;
var translateCases = JSON.parse(caseUp);

var data = JSON.stringify(translateCases)
fs.writeFile('case.json', data, finished);
function finished(err){
    console.log('All set.');
}

//////////////////////////////////////////////////// I've tried these 2 seperately ^ v


// console.log(translateCases);

console.log('Starting...')
var caseJSON = require('./case.json');
var caseTest = caseJSON.case[0 + 1]
caseTest = 0;
caseTest += 1;
// caseTestTranslate = JSON.parse(caseTest)

var actualNumber = JSON.stringify(caseTest)
fs.writeFile('case.json', actualNumber, finished)
function finished(err){
    console.log('All good.')
}

console.log(caseTest)
2 Answers

you were almost there! look closely to the order:

var cases = fs.readFileSync('case.json'); // is a string
var caseUp = cases + 1; // string + number => string, which is not what you wanted
// for this case, you can parse the filecontents first with JSON.parse on the file contents

or, what you did in the code below

var caseJSON = require('./case.json'); // now caseJSON is directly parsed as an object
// so caseJSON.case contains the value you want to increment

with this approach, it would look something like this:

var fs = require('fs');

console.log('Starting...')
var caseJSON = require('./case.json');
var caseJSONIncremented = { case: caseJSON.case + 1 }

var fileContent = JSON.stringify(caseJSONIncremented)
fs.writeFile('case.json', fileContent, finished)

function finished(err){
    console.log('All good.')
}

Raymonzut already showed a fix for your second attempt. Here are some annotations on your first one:

var fs = require('fs');
var cases = fs.readFileSync('case.json');

First off, in modern JS, var is generally not recommended. Use const when you can and let when you have to.

If you're going to use the Sync APIs, you probably want to wrap in try-catch to handle any issues with opening the file.

Note that now cases will hold a string (if there was no error.) You will have to call JSON.parse on this result to return an object. So these two lines are out of order:

var caseUp = cases + 1;
var translateCases = JSON.parse(caseUp);

But you can't just switch them, since your types won't line up. My suggestion is below.

var data = JSON.stringify(translateCases)
fs.writeFile('case.json', data, finished);
function finished(err){
    console.log('All set.');
}

I would not recommend combining the sync and async APIs in the same block of code.

An (untested) fix would look like this:

const fs = require('fs');

try {
  const str = fs.readFileSync('case.json')
  const obj = JSON.parse(str)
  // This does not change obj, but creates a clone with an updated version of `cases`
  const updatedObj = {
    ... obj
    cases: (obj.cases || 0) + 1
  }
  fs.writeFileSync('case.json' JSON.stringify(updatedObj))
} catch (e) {
  // do something here with your error.
}

This allows your configuration object to have multiple properties if you need them later, and not just cases.


Note that this is not how I would solve this. I would use Promise or async-await code instead of either the sync or async styles of fs. But this is a quick fix of your original problem in a similar style.

Related