2

I am making a browser trivia game and I have a view where a authenticated player selects a game type, which emits a socket.io event to be handled by my Node.js server, then changes the path to a "Searching for game" screen with a loading icon as the server waits enough people to join a matchmaking queue. I put a "Cancel" button on this page, which will emit another socket.io event to my server to remove the user from the matchmaking queue.

Now here is the problem, if the user presses the back button in their browser, the Cancel button is not pressed so the cancelSearch() function is not called, and therefore the socket.io emit is not sent to the server to remove the user from the search queue. Here is the relevant code...I believe I will have to add some code to my matchsearchCtrl.js file to be able to handle a back button press and call cancelSearch() accordingly..

playgame.html

<div class="container">
    <h1>Select your Game Type!</h1>
    <button class="btn btn-default btn-block" ng-click="startMatchMaking()">1v1</button>
    <button class="btn btn-default btn-block" ng-click="startMatchMaking()">2v2</button>
</div>

playgameCtrl.js

angular.module('myApp')
.controller('playgameCtrl', function($scope, $rootScope, $uibModal, socket, $location) {

    $scope.startMatchMaking = function() {
        socket.emit('joinMatchMaking', $rootScope.user.username);
        $location.path('/searching');
    }

});

matchsearch.html

<div class="container">
    <h1>Searching for players...</h1>
    <button class="btn btn-danger btn-large" ng-click="cancelSearch()">Cancel</button>
</div>

matchsearchCtrl.js

angular.module('myApp')
.controller('matchsearchCtrl', function($scope, $location, socket) {

    $scope.cancelSearch = function() {
        socket.emit('leaveMatchMaking', $rootScope.user.username);
        $location.path('/home');
    }
})

And if this is needed...

app.routes.js

myApp.config(function($routeProvider) {
    $routeProvider
    .when('/', {
        templateUrl: './app/views/landingpage.html',
        controller: 'landingpageCtrl'
    })
    .when('/home', {
        templateUrl: './app/views/home.html',
        controller: 'homeCtrl'
    })
    .when('/play', {
        templateUrl: './app/views/playgame.html',
        controller: 'playgameCtrl'
    })
    .when('/searching', {
        templateUrl: './app/views/matchsearch.html',
        controller: 'matchsearchCtrl'
    })
    .otherwise('/');
});

1 Answer 1

2

You can use JavaScript window.onbeforeunload not only to detect the back button but if the user leave the page, closing the window, for example.

window.onbeforeunload = function() {
    //Do your stuff here
}

Edit

Use $scope.$on("$locationChangeStart",function(){//Do your stuff here}); to detect the page change.

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

14 Comments

it is better to inject $window into the controller and use it instead of window.
So I will put this in my matchsearchCtrl.js file, and call cancelSearch() in the Do your stuff here line...and see if it works in a second
Your code would be more testable if you inject $window. Angular can mock the object for testing and track the functions you call on $window. And it is a good practice to use it. In future if they update the framework, you'll benefit from new features.
@Amir is right. My anwser is in pure JS. As you are using Angular i think you should follow his suggestion.
I checked one of my projects and i was using ` $scope.$on("$locationChangeStart",function(){//});` instead of window.onbeforeunload. The same as the cited post, but using $scopeinstead of $rootScope
|

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.