0

In this bug I just cant seem to find, I'm reading from a .json file called db.json updating the json and trying to write to the .json file. Although I'm parsing and stringifying the json, I'm getting this error:

SyntaxError: /Users/3x7r3m157/Development/Javascript/db.json: Unexpected end of JSON input

My code is as follows:

const args = require('yargs').argv;
const fs = require('fs');
const util = require('util');
const leaderboard = require('./db.json')

const addCompetitor = (name) => {
  leaderboard[name] = { points: [], times: [] }
  console.log(leaderboard)
  return leaderboard
}

console.log(leaderboard)

const addCompetitorTimes = (data) => {
  console.log(data)
  //this method takes a string of 'competitorName_time'
  //parses it into substrings 'name' & 'time'.

  //Afterwards it iterates through time in minutes and seconds as a string
  //in the format of '00:00', then parses the string into substrings
  //of minutes and seconds delimited by the ':' character.
  //Thereafter it converts the string to integeters and converts the time
  //into time in seconds for easy comparison of times.

  //Finally it assigns the time to the competitor in the leaderboard and
  //writes to json file db.json

  let parser = 0;
  var competitor = '';
  let times = '';
  let seconds = '';
  let minutes = '';
  let timeInSeconds = 0;

  for (let i = 0 ; i < data.length ; i ++) {
    if (parser == 0 && data[i] == '_') {
      parser ++
      continue
    }
    if (parser == 0) {
      //Stack Overflow peeps, weird error right hurrr:
      competitor += data[i]
    }
    if (parser == 1) {
      times += data[i]
    }
  }

  parser = 0

  for (let i = 0 ; i < times.length ; i ++) {
    if (parser == 0 && times[i] == ':') {
      parser ++
      continue
    }
    if (parser == 0) {
      minutes += times[i]
    }
    if (parser == 1) {
      seconds += times[i]
    }
  }

  seconds = parseInt(seconds);
  minutes = parseInt(minutes);

  let minutesInSeconds = minutes * 60

  seconds = minutesInSeconds + seconds
  leaderboard[competitor].times = seconds

  console.log(leaderboard)

  fs.writeFileSync('./db.json', JSON.stringify(leaderboard));

  return leaderboard
}

addCompetitorTimes(args.competitorTimes)

db.json:

{"Atlas":{"points":0,"times":0}}

Error with complete stack trace:

internal/modules/cjs/loader.js:800
    throw err;
    ^

SyntaxError: /Users/3x7r3m157/Development/Javascript/db.json: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at Object.Module._extensions..json (internal/modules/cjs/loader.js:797:27)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/Users/3x7r3m157/Development/Javascript/leaderboard.js:4:21)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)

2 Answers2

1

The issue is that "require" parses the json for you, but you are redundantly parsing it with json.parse. it is already an object and this fails. Just don't double parse. Requiring is enough.

Tom Boutell
  • 7,281
  • 1
  • 26
  • 23
  • Thank you! I took out the double parsing and still no dice? Will update code in my question to reflect the change – Austin Atendido Oct 13 '19 at 14:01
  • Please paste the complete error as you are receiving it now. Line numbers, all of it. – Tom Boutell Oct 13 '19 at 15:22
  • Will do, I just updated the problem to include the error with complete stack trace – Austin Atendido Oct 13 '19 at 15:34
  • it is rejecting the json file itself, so that has nothing to do with the rest of your code, I suspect that the json you pasted isn't exactly what's in the file because what you pasted looks fine. there are several good json debugger sites on the web you can paste into to check. – Tom Boutell Oct 13 '19 at 15:56
0

You're editing the file you're still reading. Change the name of the path first also I would suggest to always use a try catch when playing with JSON or Read/Write files:

  try {
   fs.writeFileSync(require.resolve('./new-db.json')), JSON.stringify(leaderboard));    
  } catch (error) {
    console.log(error)
  }
Melchia
  • 22,578
  • 22
  • 103
  • 117
  • Thank you! Yet unfortunately this solution still gives me the same error. Also is there a way I can read and write to the same file? This is a file that will be continuously updated daily as scores and times of the leaderboard change. – Austin Atendido Oct 13 '19 at 15:12
  • If there will be continuous updates you can expect collisions where reads occur during writes and where writes occur simultaneously, trashing the file. It can take a long time but eventually you will lose your data. You could wrap these calls with a lock module, but really you should use a database at this point. That's what they are there for (: – Tom Boutell Oct 13 '19 at 16:21