reactjsnext.jsqr-codeuint8tgetimagedata

Unhandled Runtime Error - TypeError: Cannot read property 'length' of undefined (Nextjs)


I am writing the code to accept QR-code image and decode into string.

The image will be static files in the folder 'public' of Nextjs.

In my code, I have convert my image into 'imageData'. I successfully convert and get 'imageData' object that return with A Uint8ClampedArray.

ImageData object's console.log in browser

Then, I use this npm library to do javascript QR reader. https://www.npmjs.com/package/jsqr

But, somehow it give me this error back to me.

Unhandled Runtime Error TypeError: Cannot read property 'length' of undefined

This is error show in my localhost:3000

Error in localhost:3000

This in when I look in my code editor. I have highlight in line 372.

Where in detect in my code editor

Although, I think that line 372 in part of the .next library and I should not have to do anything to it.

May be it is my code then.

This my code.

index.js

import Head from 'next/head'
import styles from '../styles/Home.module.css'
import jsQR from 'jsqr'
import { useEffect } from 'react'

export default function Home() {

  useEffect(() => {
    const canvas = document.getElementById("canvas");
    const ctx = canvas.getContext('2d');
    const width = 200;
    const height = 200;

    const image = new Image;
    var imageDataT
    image.src = './Test_QR_Coupon.png'
    image.onload = () => {
      ctx.drawImage(image, 0, 0,width,height);
      imageDataT = ctx.getImageData(0, 0, 200, 200);
      console.log(imageDataT);
    }

    const code = jsQR(imageDataT, 300, 300,'dontInvert')
    console.log('Code:', code)
    if (code) {
      console.log("Found QR code", code);
    }
  })

  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <canvas id="canvas"></canvas>
      </main>

      <footer className={styles.footer}>
        <a
          href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          Powered by{' '}
          <img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
        </a>
      </footer>
    </div>
  )
}

Solution

  • You get undefined error because you call the jsqr function before the onload callback where you define imageDataT. You need to wrap the code inside the callback.

    var imageDataT
    image.src = './Test_QR_Coupon.png'
    image.onload = () => {
      ctx.drawImage(image, 0, 0,width,height);
      imageDataT = ctx.getImageData(0, 0, 200, 200);
      console.log(imageDataT);
      const code = jsQR(imageDataT, 300, 300,'dontInvert')
      console.log('Code:', code)
      if (code) {
        console.log("Found QR code", code);
      }
    }