quaggaJS icon indicating copy to clipboard operation
quaggaJS copied to clipboard

Quagga.onDetected does not stop firing after Quagga.stop()

Open tasoskakour opened this issue 7 years ago • 19 comments

Hello.

It seems like when I command Quagga to stop (Quagga.stop), the on Detected registered function doesn't stop to fire up, when I re-initialize Quagga with new parameters.

For example:

  1. Quagga starts for first time, I register the function foo() to Quagga.onDetected
  2. I stop Quagga with Quagga.stop()
  3. I re-initialize Quagga and re-register the function foo() to Quagga.onDetected
  4. I observe that when the onDetected fires, then the foo() is called two times. (So the first onDetected from the step (1) still fires!) 5)..Again and again

Thoughts?

tasoskakour avatar Feb 12 '18 16:02 tasoskakour

As a workaround you could manually call offDetected(), I guess

jampy avatar Apr 07 '18 07:04 jampy

We should test this, and see if we are leaking by doing this, as well as causing undesired behavior.

ericblade avatar Jun 08 '18 07:06 ericblade

I have same problem

johanroug avatar Mar 16 '20 20:03 johanroug

offDetected()

calling offDetected() doesn't work for me. I still have the same behavior like calling stop() only.

edited: ------------------------------------ just to make it complete my issue vanished when correctly calling

Quagga.offProcessed(onProcessed); 
Quagga.offDetected(doOnDetected); 
Quagga.stop();

when my component is unmounted.

hbinkle avatar May 25 '20 06:05 hbinkle

Hello, I've had the same problem when I used QuaggaJS.

To solve this problem, I just called the function OffDetected() at the end of the function OnDetected(). After that, the OnDetected just call my AJAX request once for every barcode read.

Thanks

moisesjunior avatar Oct 28 '20 14:10 moisesjunior

Hello, I have the same issue ! I tried to add OffDetected(), when I scan a barcode, it calls just once the method OnDetected but if I want to scan another barcode it does not work anymore.

kabamamadyit avatar Nov 09 '20 20:11 kabamamadyit

fwiw, i was never able to recreate these problems, and automated testing hasn't revealed them, so i suspect that there's some errors in people's logic wrt calling on/off multiple times and in the wrong places.

ericblade avatar Nov 09 '20 21:11 ericblade

My code is based on this angular project : https://github.com/classycodeoss/mobile-scanning-demo

This seems to work when the cart and the scanner are implemented on the same page. On my side I have one angular component for the scanner and another for the cart. But before even getting to the cart, when I scan, it goes multiple times in the onDetected method. See the code below please :

//Init:

Quagga.init({
    inputStream: {
      constraints: {
        facingMode: 'environment'
      },
      area: { // defines rectangle of the detection/localization area
        top: '40%',    // top offset
        right: '0%',  // right offset
        left: '0%',   // left offset
        bottom: '40%'  // bottom offset
      },
    },
    decoder: {
      readers: ['ean_reader']
    },
  },
  (err) => {
    if (err) {
      this.errorMessage = `QuaggaJS could not be initialized, err: ${err}`;
    } else {
      Quagga.start();
      Quagga.onDetected((res) => {
        this.onBarcodeScanned(res.codeResult.code);
      });
    }
  });

setTimeout(() => {
  this.updateService.checkForUpdates();
}, 10000);

//onDetected method fired

onBarcodeScanned(code: string) {

   // ignore duplicates for an interval of 1.5 seconds
   const now = new Date().getTime();
   if (code === this.lastScannedCode && (now < this.lastScannedCodeDate + 1500)) {
     return;
   }

   // ignore unknown articles
   const article = this.catalogue.find(a => a.ean === code);
   if (!article) {
     return;
   }

   this.shoppingCart.addArticle(article);

   this.lastScannedCode = code;
   this.lastScannedCodeDate = now;
   this.beepService.beep();
   this.changeDetectorRef.detectChanges();
}

kabamamadyit avatar Nov 09 '20 21:11 kabamamadyit

I think the OnDetected function must be called outside init function.

moisesjunior avatar Nov 09 '20 21:11 moisesjunior

Thanks I did that, but if you put a console.log() at the begin of the method called in onDetected, you will see, it's called multiple times even when you call onDetected method outside of init.

kabamamadyit avatar Nov 09 '20 21:11 kabamamadyit

@kabamamadyit ... I'm not sure what you're expecting to have happen here? If you don't stop the scanning, then it will continue scanning.

ericblade avatar Nov 09 '20 23:11 ericblade

@ericblade okay so thanks for the answer. What I am telling is that when I stop it with Quagga.offDetected(), I cannot scan anymore.

What I am trying to do is to be able to scan several barcodes, one by one, before going to the cart page. When I put Quagga.offDetected() at the end of Quagga.onDetected(), I am able to scan one barcode and it stops. So that's good but when I try to scan another barcode, without changing pages, the event onDetected does not fire anymore. I have to refresh the page to be able to scan again.

But if I don't put Quagga.offDetected(), when I scan one barcode, it acts like I am scanning multiple barcodes at the same time.

I just want a user to be able to scan several barcode before checking out his cart, like going to a store, picking all the items you need and then checkout your cart.

So my main question would be, should we use Quagga.offDetected() ? if yes, where should we put it so it can allow us to scan barcodes one by one please ?

kabamamadyit avatar Nov 10 '20 17:11 kabamamadyit

In my particular application, when I get a valid code that I'm accepting into my onDetected callback, I call Quagga.stop() and turn off the entire camera function of the app, removing the scanner area from the app, until the user clicks the start camera button again.

If you want to be able to scan multiple items, I'd guess that you probably want to do it similarly to what you have -- play a sound or other indicator so the user knows something has happened, set a flag that stops processing for a moment, so the user has time to move to another code, and set a timeout to clear that flag.

You could also do it by calling offDetected to remove your function, then use onDetected to put it back in a timeout. Or you could call .stop then .start .. there are many ways to do it, although i'd probably use a boolean flag, it would be probably the easiest and least noticeable to the user (as calling .stop then .start will definitely cause a UI lag on many devices as it turns off/on the camera)

I'm happy to help, for sure, though I do want to make it clear that I think this is not a problem in the library, itself, more just figuring out what your specific application wants to do after detecting a barcode. In my case, I come to a full stop, and handle everything related to that barcode, and the user selects when to continue. IN your case, I think you want to put a brief timeout on it, just so that the user knows to go to the next item.

ericblade avatar Nov 10 '20 19:11 ericblade

Thank you for these information. It makes perfect sense. I will in that case use the solution of calling offDetected to remove the function and use onDetected to put it back in a timeout. It would be the best solution for me. thanks

kabamamadyit avatar Nov 10 '20 20:11 kabamamadyit

Just thought I would leave an answer that makes it work just by coping and pasting this code. All because I love you guys! lol

index.php

`

maximusmcc avatar Apr 04 '23 19:04 maximusmcc

`import React, { useEffect } from "react"; import config from "./config.json"; import Quagga from "quagga";

const Scanner = (props) => { const { onDetected } = props;

useEffect(() => { Quagga.init(config, (err) => { if (err) { console.log(err, "error msg"); }

  Quagga.start();
});

//detecting boxes on stream
Quagga.onProcessed(onProcessed);

Quagga.onDetected(detected);

return () => {
    Quagga.offDetected(detected);
  };

}, [onDetected]);

const onProcessed = (result) => {
    var drawingCtx = Quagga.canvas.ctx.overlay,
        drawingCanvas = Quagga.canvas.dom.overlay;

    if (result) {
        if (result.boxes) {
            drawingCtx.clearRect(
                0,
                0,
                Number(drawingCanvas.getAttribute("width")),
                Number(drawingCanvas.getAttribute("height"))
            );
            result.boxes
                .filter(function (box) {
                    return box !== result.box;
                })
                .forEach(function (box) {
                    Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, {
                        color: "green",
                        lineWidth: 2
                    });
                });
        }

        if (result.box) {
            Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, {
                color: "#00F",
                lineWidth: 2
            });
        }

        if (result.codeResult && result.codeResult.code) {
            Quagga.ImageDebug.drawPath(
                result.line,
                { x: "x", y: "y" },
                drawingCtx,
                { color: "red", lineWidth: 3 }
            );
        }
    }
}

const detected = (result) => { if (result.codeResult.code.toLowerCase().includes("assetid")) { Quagga.offDetected(detected); onDetected(result.codeResult.code); } };

useEffect(() => { return () => { Quagga.offProcessed(onProcessed); Quagga.offDetected(detected); Quagga.stop(); } }, []);

return ( // If you do not specify a target, // QuaggaJS would look for an element that matches // the CSS selector #interactive.viewport <div id="interactive" className="viewport" /> ); };

export default Scanner; `

My issue is when the component is destroyed the camera is not turing off, even if i do stop(). I tried all possible ways but still none of them work

BISWAJITABISWAL avatar Nov 18 '23 16:11 BISWAJITABISWAL

@BISWAJITABISWAL I tried passing your code to Prettier, so that it would format it in a way that is readable, and it's unable to parse your code due to syntax errors. Your code doesn't work at the very least, because there are straight up errors in the code.

ericblade avatar Dec 01 '23 07:12 ericblade

You can see my code working at https://a1sold.com I do not know where you copied it from. If it is on a website for code copy you may have to look at the quotes or other scripts interfering with the code. . I know it sucks. That is why I usually provide the code in a zip download.

Thanks

Click Here To Subscribe To My Posts, I talk about the latest and greatest tools to help you become more efficient on the web! ;-) https://feedburner.google.com/fb/a/mailverify?uri=A1websiteprocom&amp;loc=en_US

Maximus McCullough

"Never Give Up" - Faith McCullough

.[image: A1WebsitePro.com]. https://feedburner.google.com/fb/a/mailverify?uri=A1websiteprocom&amp;loc=en_US

[image: A1WebsitePro.com][image: A1WebsitePro.com] http://A1WebsitePro.com

[image: web develpment facebook] https://www.facebook.com/pages/A1WebsitePro/139087542802830 [image: web develpment twitter] https://www.twitter.com/a1websitepro https://plus.google.com/104022008385832589501/posts [image: web develpment google plus] https://pinterest.com/a1websitepro[image: web develpment youtube] https://www.youtube.com/user/MaximusMccullough?feature=mhee [image: web develpment LinkedIn] https://www.linkedin.com/pub/maximus-mccullough/50/501/789 [image: web develpment rss] http://feeds.feedburner.com/A1websiteprocom

On Fri, Dec 1, 2023 at 2:13 AM Eric Blade @.***> wrote:

@BISWAJITABISWAL https://github.com/BISWAJITABISWAL I tried passing your code to Prettier, so that it would format it in a way that is readable, and it's unable to parse your code due to syntax errors. Your code doesn't work at the very least, because there are straight up errors in the code.

— Reply to this email directly, view it on GitHub https://github.com/serratus/quaggaJS/issues/262#issuecomment-1835583510, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABZCL4O7I3KJ44SNU5DFDWLYHF7RXAVCNFSM4EQJUAJ2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBTGU2TQMZVGEYA . You are receiving this because you commented.Message ID: @.***>

maximusmcc avatar Dec 01 '23 11:12 maximusmcc

I was responding to @BISWAJITABISWAL there

ericblade avatar Dec 01 '23 18:12 ericblade