4

i'm building a chrome app with USB device. In my main app.js i want always check when device added/removed and change url.

angular.module('rfApp', [
    'ngRoute',
    'ngMaterial',
    'rfApp.view1',
    'rfApp.view2',
    'rfApp.device_not_found'
]).config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) {
    $locationProvider.hashPrefix('!');

    function checkForDevices() {
        RFFWHID.getDevices(function(current_devices) {
            if(current_devices.length > 0) {
                $routeProvider.otherwise({redirectTo: '/view1'});
            } else {
                $routeProvider.otherwise({redirectTo: '/device_not_found'});
            }
        });
    }

    chrome.hid.onDeviceAdded.addListener(function(){
        checkForDevices();
    });
    chrome.hid.onDeviceRemoved.addListener(function(){
        checkForDevices();
    });

    checkForDevices();

}]);

But redirect not working in async function.

Edit:

I found similar question How to call $urlRouterProvider.otherwise() after loading JSON file?, and first answer describes that it is impossible. But how i can solve this problem. I need to check for usb remove/add globally and change views based on that.

Community
  • 1
  • 1
Arti
  • 7,356
  • 12
  • 57
  • 122

1 Answers1

1

It's hard to debug since i don't have the environment for chrome apps right now, but you could change approach. Rather than redirecting with $routeProvider, you could use $routeChangeSuccess:

angular.module('rfApp')
.factory('deviceManager', ($rootScope) => {
    let deviceConnected = false;
    
    chrome.hid.onDeviceAdded.addListener(function() {
        checkForDevices();
    });
    chrome.hid.onDeviceRemoved.addListener(function() {
        checkForDevices();
    });

    checkForDevices();
    return {
        isDeviceConnected: isDeviceConnected
    };

    function isDeviceConnected() {
        return deviceConnected;
    }

    function checkForDevices() {
        RFFWHID.getDevices(function(current_devices) {            
            deviceConnected = current_devices.length > 0;
            $rootScope.$emit('deviceChange');
        });
    }    
})
.run(($rootScope, $location, deviceManager) => {
    $rootScope.$on('$routeChangeSuccess', checkAndRedirect);
    $rootScope.$on('deviceChange', checkAndRedirect);

    function checkAndRedirect() {
        if (deviceManager.isDeviceConnected()) {
            $location.url('/view1')
        } else {
            $location.url('/device_not_found');
        }
    }
});

So basically every time the state changes, you check if the device is connected in a synchronous way and you can redirect the user using $location.url or whatever fits best to you.

Edit: I added a custom $rootScope event, that is fired when a device is connected/disconnected. Your application should now change state automatically every time the event is fired.

pietrovismara
  • 6,102
  • 5
  • 33
  • 45
  • thanks for answer but, it doesn't work:( So when USB device added i should do this `if (deviceManager.isDeviceConnected())` and then do redirect to view. – Arti Jan 20 '17 at 14:19
  • @Arti When a device is connected you do `checkForDevices`, you use `isDeviceConnected` just to check sync if there's at least one device, without having to wait `RFFWHID.getDevices`. Sorry but i didn't have the chance to test it, this is just an example to give you an idea of the approach you could follow. Btw, do you have any errors? Why it is not working? Maybe i can improve it. – pietrovismara Jan 20 '17 at 14:36
  • problem that this hit `$rootScope.$on('$routeChangeSuccess'` only once when i change urls. But when i running app and remove device it fire `chrome.hid.onDeviceRemoved` and my url should change – Arti Jan 20 '17 at 14:40
  • You can test any async function – Arti Jan 20 '17 at 14:49
  • @Arti Check it now – pietrovismara Jan 20 '17 at 14:51
  • nothing happen. Seems like url is changing, but view doesn't. Only if i after remove device click somewhere then it go to device_not_found page – Arti Jan 20 '17 at 15:10
  • also i tried without factory. All code in run function. Does it matter ? – Arti Jan 20 '17 at 15:12
  • The factory is there just as a good practice to separate functionality in your code. It should work the same, but i strongly suggest you to keep it. If you don't follow my code, it's harder for me to understand what's wrong. Please try to replace `$location.url(path)` with `$window.location.href = path;` – pietrovismara Jan 20 '17 at 15:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/133652/discussion-between-pietrovismara-and-arti). – pietrovismara Jan 20 '17 at 15:21