2
votes

Currently I am working on a phonegap that uses the Barcode Scanner plugin (v 0.6.0) with phonegap 2.9.0. The actual barcode scanner works fine, I can get the phone to bring up the camera/scanner and read a barcode. I can even get the result.text to show up in a simple alert (as long as I do this in the callback). However, if I try to save the value of results.text into a global variable or hidden field, the value is undefined in the variable, and empty in the field.

my current code

openBarcodeScanner();
var code = document.getElementById('barcode').value;
alert(code);

function openBarcodeScan(viewInfo){
var scanner = cordova.require("cordova/plugin/BarcodeScanner");
scanner.scan(function (result){
    document.getElementById('barcode').value = result.text;
    },
    function (error){
        alert ( error );
    });
}

I might very well be doing something stupid, but for the life of me can't figure it out. I would prefer to use a global variable, but the hidden field was a last ditch effort to pass the result.text outside the call back.

EDIT: I guess this because of the asynchronous callback, but I'm not sure how get result.text outside the function.

2
The .scan() method is asynchronous (it's usually a sign when a method accepts a callback instead of returning a value that it's asynchronous), so the function you provide to .scan() will not execute immediately, therefore it won't set the value when you expect it to and won't be available for retrieval by your outside code where you do alert(code);Ian
@Ian is there a way to get around that, or should I rethink my approach?BrianM
Well there's no way to modify the synchronous behavior, so I'm thinking you need to rethink your approach. What is your overall approach? You just talk about being able to get the value globally, but what are you actually trying to do with it?Ian
I'm trying to send the result with some properties from an object to a URL as string queries. I'm looking at the Jquery API right now, I think I might be able to use .ajaxComplete()BrianM
So inside of the .scan() first callback, write the AJAX request there. You have access to result, and then you should be able to access any of these object properties you speak ofIan

2 Answers

4
votes

The .scan() method is asynchronous (it's usually a sign that it's asynchronous when a method accepts a callback instead of returning a value). So the first function you provide to .scan() will not execute immediately, therefore it won't set the value when you expect it to and won't be available for retrieval by your outside code where you do alert(code);.

Since all you need it for is to make an AJAX request, you might as well put the request inside of the scan callback, like:

scanner.scan(function (result) {
    // Make AJAX request, using `result`
}, function (error) {
    alert(error);
});

You could also set it up so that your openBarcodeScan function accepts a callback, and run that callback when the scan is a success, like:

function openBarcodeScan(viewInfo, callback) {
    var scanner = cordova.require("cordova/plugin/BarcodeScanner");
    scanner.scan(function (result) {
        callback(result);
    }, function (error) {
        alert(error);
    });
}

And call it like:

openBarcodeScan("whatever", function (barcode) {
    // Make AJAX request, using `barcode`
});

Technically, your function could be reduced to:

function openBarcodeScan(viewInfo, callback) {
    var scanner = cordova.require("cordova/plugin/BarcodeScanner");
    scanner.scan(callback, function (error) {
        alert(error);
    });
}
1
votes

You need to pass functions for callback to .scan() so they can be called after the scan intent finishes. You want something like this:

scanner.scan(success,error);

function success(result) {
  document.getElementById('barcode').value = result.text;
}

function error(error) {
  alert(error);
}