d
Amit DhamuSoftware Engineer
 

Load JSON via file input in React

3 minute read 00000 views

Say we had a requirement to read the contents of a JSON file passed to our application via a file input. We can utilise the FileReader API to read the contents of the file directly on the client.

Take our simple file input component below which is using React.

const FileInput = () => {
  const onChange = () => {}

  return (
    <input type="file" accept=".json,application/json" onChange={onChange} />
  )
}

export default FileInput

Next, let's write a function which will parse the JSON (we'll leave the onChange handler empty for now).

This function doesn't need to be redeclared each time the component renders so feel free to place this outside of it.

const readJsonFile = (file: Blob) =>
  new Promise((resolve, reject) => {
    const fileReader = new FileReader()

    fileReader.onload = event => {
      if (event.target) {
        resolve(JSON.parse(event.target.result as string))
      }
    }

    fileReader.onerror = error => reject(error)
    fileReader.readAsText(file)
  })

This will be used in conjunction with our onChange handler. It will load a file's Blob data and attempt to parse it with JSON.parse.

Now, lets fill out the onChange handler.

const onChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
  if (event.target.files) {
    const parsedData = await readJsonFile(event.target.files[0])

    console.log(parsedData)
  }
}

You should now see the contents of the JSON file in the console.

Full Code

const readJsonFile = (file: Blob) =>
  new Promise((resolve, reject) => {
    const fileReader = new FileReader()

    fileReader.onload = event => {
      if (event.target) {
        resolve(JSON.parse(event.target.result as string))
      }
    }

    fileReader.onerror = error => reject(error)
    fileReader.readAsText(file)
  })

const FileInput = () => {
  const onChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
    if (event.target.files) {
      const parsedData = await readJsonFile(event.target.files[0])

      console.log(parsedData)
    }
  }

  return (
    <input type="file" accept=".json,application/json" onChange={onChange} />
  )
}

export default FileInput