1

I struggled to title this question but basically I'm just starting off with angular and am using ngMaterial. I have a toast created by using an angular factory

app.factory('notify', ['$mdToast', '$animate', function($mdToast, $animate) {
    return {
        showToast: function(msg) {
             var toast = $mdToast.simple()
                  .content(msg)
                  .action('Close')
                  .highlightAction(false)
                  .position('top right');
            $mdToast.show(toast).then(function() {
              //
            });
        }
    }
}]);

This works great if I have a button on the page that activates the toast however I have socket.io running as well with node monitoring redis for updates to pop up that notification. However I can't get it to work as I'm not quite sure how I can call that factory from within here

socket.on('notification.new', function (data) {        
    //call factory here to show toast
    console.log(data);
});

I know if I have it on a controller I can do it by using

angular.element().scope().showToast(data)

But I don't want to create an element just to house the controller to call the function.

projectxmatt
  • 3,091
  • 2
  • 15
  • 16
  • 1
    There's an Angular socket service you can make (https://github.com/btford/angular-socket-io) - else you can use `angular.element` to target ANY element inside the controller and get the `scope` from that. – tymeJV Dec 11 '14 at 21:51
  • Not much time to write a full response, but I think your issue is that you're trying to interface naked JS with Angular at all. it's not really designed for that. I'd abstract sockets into an angular service, inject that into whatever controller or service I want to use it in, and set up listeners there. Then you can also use mock sockets for tests. – Mallen Dec 11 '14 at 21:52
  • Thanks @tymeJV that lead me down the right path and found a way to easily wrap the socket functions I needed into angular and then it was a breeze to get going. – projectxmatt Dec 12 '14 at 14:46

2 Answers2

0

What I did to solve this issue is I attached one of the functions inside the controller to the window object. So something like

window.showToast = function(msg) {
             var toast = $mdToast.simple()
                  .content(msg)
                  .action('Close')
                  .highlightAction(false)
                  .position('top right');
            $mdToast.show(toast).then(function() {
              //
            });

Then, from within the socket io listener (or any raw javascript for that matter):

socket.on('notification.new', function (data) {        
    //call factory here to show toast
    window.showToast(data); //or however you'd like
});

And that kind of worked for me. I know this is not the best approach but since this question didn't have any answers at all I thought I'll post a workaround that at least does the job done.

Muhammad bin Yusrat
  • 1,433
  • 1
  • 14
  • 19
-1

You need to get hold of Angular services to use Angular in a raw Javascript.

Refer to Call Angular JS from legacy code

  • angular.element(domElement).scope() to get the current scope for the element
  • angular.element(domElement).injector() to get the current app injector
  • angular.element(domElement).controller() to get a hold of the ng-controller instance.

In your case use injector service to get hold of your factory.

Update 1

$injector reference

Community
  • 1
  • 1
bhantol
  • 9,368
  • 7
  • 44
  • 81