Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this have $rootscope.$new()?

Tags:

angularjs

I am researching how to use Jasmine with Karma. I am trying to inject a scope into my controller and from somewhere I have picked up this code...

var scope = { message: 'hello' };

beforeEach(angular.mock.module('myApp'));

beforeEach(angular.mock.inject(function ($rootScope, $controller) {

    scope = $rootScope.$new();

    $controller('myController', { $scope: scope });

}));

The problem is that the scope is being wiped out with the line...

scope = $rootScope.$new();

So I can comment it out but I am wondering what the use of this line is for? When would I want to call $rootscope.$new()? I understand it is to do with isolation but I don't really get the practical applications of it.

UPDATE : As Tim points out below it is a problem because I have declared my own scope. So I can modify the code to be ....

var scope;

beforeEach(angular.mock.module('myApp'));

beforeEach(angular.mock.inject(function ($rootScope, $controller) {

    scope = $rootScope.$new();

    scope.message = 'hello';

    $controller('myController', { $scope: scope });

}));

And that works more like expected, but I am still wondering what the best approach is? What is $rootscope.$new() even for?

like image 843
Exitos Avatar asked May 07 '14 14:05

Exitos


People also ask

What is the use of $rootScope?

Root Scope All applications have a $rootScope which is the scope created on the HTML element that contains the ng-app directive. The rootScope is available in the entire application. If a variable has the same name in both the current scope and in the rootScope, the application uses the one in the current scope.

What is alternative of rootScope in Angular?

In similar way, you can use use the sharedService inside any component & fetch the returing output and used inside your view. That's it. I found this solution as a good alternative of rootScope. You can use this inside your angular 2/4 application.

What is the difference between $scope and $rootScope?

$rootscope is available globally (for all Controllers), whereas $scope is available only to the Controller that has created it.

How many rootScope can AngularJS application have?

Each AngularJS application has exactly one root scope, but may have any number of child scopes.


2 Answers

$rootScope.$new creates a new instance of $rootScope.Scope that inherits from $rootScope. In other words, it creates a new child scope of $rootScope.

The reason you might use it in tests (such as the one you posted), is because your other alternative is to use $rootScope itself. Doing so might create a mess since it might be used all over the place.

I consider as best practice to create (and destroy afterwards) a new scope for each test case.

Here's your example rewritten to what I consider a best practice:

describe('myModule', function() {

    var $rootScope;

    beforeEach(module('myModule'));

    beforeEach(function() {
        inject(function(_$rootScope_) {
            $rootScope = _$rootScope_;
        });
    });

    describe('myController', function() {

        var $scope;

        beforeEach(function createChildScopeForTheTest() {
            $scope = $rootScope.$new();
        });

        afterEach(function disposeOfCreatedChildScope() {
            $scope.$destroy();
        });

        it('tests something', function() {
            $scope.message = 'hello';

            $controller('myController', { $scope: $scope });

            expect($scope.something).toEqual('world');
        });
    }); 
});
like image 128
ethanfar Avatar answered Sep 27 '22 21:09

ethanfar


Scopes in angular are nested in parent child relationships, all deriving from a single parent $rootScope

This is how angular creates the $scope that gets injected into your controller so it creates the same experience when you are unit testing your controller.

This is especially useful if you are doing anything in your controller which requires you to call $apply rather than you having to mock that out as well.

like image 32
Brocco Avatar answered Sep 27 '22 19:09

Brocco