1

I made a simplified example of the issue below. Basically the "this.content" variable doesn't get changed by the "socket.on" event (which is otherwise working properly).

index.html:

<div ng-controller="gameController as game">
    <button ng-click="game.buttonClick()">This changes the text when clicked.</button>
    <div>{{ game.content }}</div>
</div>

controller.app:

app.controller('gameController', function($scope, $http) {
    this.content = "Default";

    this.buttonClick = function() {
        this.content = "Content changes to this, when the button is clicked.";
    };

    socket.on('gameFound', function () {
        this.content = "Content doesn't change to this, when a message is emitted.";
        console.log("This message is being logged into the console though.");
    });
});

On the server-side, I have a socket.emit('gameFound', "Something"), which is working properly.

I think the issue is that "this.content" is referring to something else in the context of socket.on.

How can I change the value of "this.content" in the socket.on function?

Any help is appreciated.

1 Answer 1

1

I think the context is wrong, try:

app.controller('gameController', function($scope, $http) {
    var self = this;
    self.content = "Default";

    this.buttonClick = function() {
        self.content = "Content changes to this, when the button is clicked.";
    };

    socket.on('gameFound', function () {
        self.content = "Content doesn't change to this, when a message is emitted.";
        console.log("This message is being logged into the console though.");
    });
});

Doing this.content inside socket.on actually meant socket.content and not gameController.content as you expected.

Another approach, would be is: to bind it's context to the outside,

socket.on('gameFound', function () {
  this.content = "Content doesn't change to this, when a message is emitted.";
  console.log("This message is being logged into the console though.");
}.bind(this));

If you want angular to update the view when the content gets updated, you'll have to call it manually. Angular doesn't know if the content got updated because there was no interaction with the DOM. Try this instead:

socket.on('gameFound', function () {
    self.content = "Content doesn't change to this, when a message is emitted.";
    console.log("This message is being logged into the console though.");
    // update the view
    $scope.$apply();
});
Sign up to request clarification or add additional context in comments.

5 Comments

That makes a lot of sense, however it doesn't seem to work this way either :( EDIT: Just tried the second solution too, the content didn't change again.
Yup, just tried it a second ago, and for some reason it doesn't work. The console logs that 'gameFound' is emitted properly, however the content of the {{ game.content }} stays the same.
@Neekoy do you wan't angular to update the view? Angular doesn't know you changed the value. So execute $scope.apply() after changing the content.
Oh my, you're super awesome. It gave me a "not a function error" and when I googled it, the correct syntax is $scope.$apply(); which did the trick. Thank you so very much.
@Neekoy, sorry I haven't used angular for over a year :D But glad it worked.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.