0

I am trying to call a controller's function from within a script tag in my index.html.

<script>
    var socket = io.connect('192.168.1.103:3000');
    socket.emit('pusharduino', "SOCKET DATA FROM ANGULAR");
    socket.on('pushangular', function (data) {
        testFunction();
    });
</script>

<button ng-controller="BaseCtrl" ng-click="testFunction()"></button>

The socket.io connection works fine. It connects to my server and whenever I emit anything either way it sees it just fine. The issue is "testFunction()" is not defined apparently.

The button directly below it works fine! The "testFunction()" function is defined in the BaseCtrl controller of my app. Obviously since I attached that controller to the button I am able to call the function.

The question is; how do I call that same function from within my socket.io script there? Or any script tag for that matter? Doesn't even need to be socket.io, its just that socket.io is the trigger for this specific event.

I assume it is some scope issue here and that script clearly doesn't have access to the BaseCtrl. I am able to print out global variables that are in my app.js though.

THINGS I'VE TRIED: - Attaching the BaseCtrl to the script tag. - Using $scope all over the place. - Referencing the testFunction() in every way I can think of.

CODE FOR BaseCtrl

angular.module('yapp')
 .controller('BaseCtrl', function($scope) {

   $scope.testFunction = function() {
     console.log("testFunction() has been called!);
   }

});

----------------------------------------------------------------------------

(tl;dr)

IN SUMMARY: How can I make a function in my app available to my html so that whenever socket.on('whatever') is triggered, that function will be called? I don't care if the function is in a factory, a service, a controller, doesn't matter to me. I just need to update a bunch of variables in my app whenever they are received from the server via socket.io

7
  • move it to a service. simple as that. You already hinted at that in your quesiton. Commented Sep 22, 2015 at 19:50
  • 1
    Thanks for the down-vote... the reason I'm asking this is because I am a complete beginner to all this and don't really understand what I am doing. I hinted that I could move it to a service because I thought somebody might say that, but I don't understand how to do that. I barely understand my own question. Commented Sep 22, 2015 at 20:05
  • 3
    html5rocks.com/en/tutorials/frameworks/angular-websockets is decent. Commented Sep 22, 2015 at 20:06
  • 1
    Thank you Kevin, I will read through that. I must ask though; is it even possible to call the function from the HTML script tag? Also, when you say to move it to the service, are you referring to the function that needs called, or are you referring to the socket.io connection itself? I tried calling a function that is in a factory and that also didnt work. I am not sure how to make services/factories available to this script. Commented Sep 22, 2015 at 20:07
  • Just the socket.io part, the function would be something you give as a callback to the service (or factory, however you define it) That function is not accessible outside of the controller or its template. Commented Sep 22, 2015 at 20:16

1 Answer 1

1

In your script you can do the following

var parentScope = window.parent.angular.element(document.body).scope();
parentScope.$emit("MyEvent", { payload: "MyPayload"});

In your controller you can just listen to the event.

$scope.$on("MyEvent", function (evt, args) {
//arg is your payload
}

Hope that helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Holy molly it worked!!! This is exactly what I needed. I will need to do some research to truly understand what is going on here but I am very happy that you got it to work. I will also be continuing down the path that @Kevin B set me on since it looks like the most popular method (putting socketio in a service), but as far as this question goes, THIS is the answer I was looking for. Thank you!
I would agree making it a service makes sense. This is a neat trick to have in your back pocket when you need something outside of angular to communicate with angular. For example, you can use this technique in iFrames that need to communicate back to the parent frame(Angular app). Only difference there is you need change the line where you define scope to this: var parentScope = window.parent.angular.element(window.frameElement).scope();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.