AngularJS scope in unit test



  • Before I start, My JavaScript is rusty af.

    I'm going through the phonegap tutorial on the Angularjs site. I have a controller that looks like this

    var phonecatApp = angular.module('phonecatApp', []);
    
    // Define the `PhoneListController` controller on the `phonecatApp` module
    phonecatApp.controller('PhoneListController', function PhoneListController($scope) {
      $scope.phones = [
        {
          name: 'Nexus S',
          snippet: 'Fast just got faster with Nexus S.'
        }, {
          name: 'Motorola XOOM™ with Wi-Fi',
          snippet: 'The Next, Next Generation tablet.'
        }, {
          name: 'MOTOROLA XOOM™',
          snippet: 'The Next, Next Generation tablet.'
        }
      ];
    });
    

    and the unit test is

    describe('PhoneListController', function() {
        beforeEach(module('phonecatApp'));
    
        it('should create a phone model with 3 phones', inject(function($controller) {
            var scope = { };
            var ctrl = $controller('PhoneListController', {$scope: scope})
            expect(scope.phones.length).toBe(3);
        }));
    });
    

    Now the test passes. I don't understand the line in the unittest where it says

    { $scope : scope }
    
    

    So there are three phone objects in the controller but we pass in a empty object to the controller ? yet the test passes ? I don't know what the fuck is going on here.

    1. What does the line do exactly?
    2. How does the test pass if we pass an empty scope object with no phones into the controller ?

  • Notification Spam Recipient

    Welcome back!

    So far as I can tell, {$scope: scope} is just an object with a property $scope set to scope (which itself is an empty object).

    It's basically the same thing as {$scope : {}}

    Beyond that, I dunno.

    Edit: except the controller is modifying the passed-in $scope I guess, which comes out and modifies the scope in turn?

    I guess I'm a little rusty with js myself...



  • You basically wrote down my train of thought. I'm guessing this must be some pass by reference mischief that modifies what is sent in ?!?!?! Arghh. I hate it when I don't get something ten mins into a tutorial and don't even know what to google for.

    Also, I was expecting an obligatory "JavaScript is the real WTF" comment. I'll wait for it.



  • I've never used angular 1, but this seems pretty clear to me.

    You create an object scope that doesn't have any properties. Then you create an instance of PhoneListController and give it an object with options, where one of the options, under the name $scope is your scope object.

    Don't get confused by $ in these names. This is just some kind of convention, they could have named it "foo", it would have worked the same.

    Inside the PhoneListController constructor function, your scope object is now given as $scope local variable. So when your constructor does $scope.phones = , it is actually mutating your scope object from the unit test. Then you expect that this mutation did in fact occur.

    This is just a way to inject your own little "portal" into the controller, so that you can test for changes as your controller code is being run.



  • @cartman82 said in AngularJS scope in unit test:

    Inside the PhoneListController constructor function, your scope object is now given as $scope local variable. So when your constructor does $scope.phones =, it is actually mutating your scope object from the unit test. Then you expect that this mutation did in fact occur.

    This is exactly what I was confused about. Thank you.


  • Considered Harmful

    Javascript is TR:wtf:.
    did i do good



  • @stillwater said in AngularJS scope in unit test:

    I'm going through the phonegap tutorial on the Angularjs site.

    Stop what you are doing. It seems you are using this tutorial. There's a notification bar at the top of the page that says:

    This site and all of its contents are referring to AngularJS (version 1.x), if you are looking for the latest Angular, please visit angular.io.

    Are you sure you want to learn an old version of Angular? Is there an actual reason to do so (e.g. you need to support an existing application written in it, or you are interested in updating Cobolno longer popular projects)? New versions of Angular have significant improvements, e.g. good integration with TypeScript which is critical for larger applications.

    TRWTF is Angular's cadence of "a major release with easy-to-migrate-over breaking changes every 6 months."


    @cartman82 said in AngularJS scope in unit test:

    Don't get confused by $ in these names. This is just some kind of convention, they could have named it "foo", it would have worked the same.

    That's not entirely right (but it may work correctly in the test nonetheless).

    1. "Scope" is Angular's term for "context holder", similar to React's state or a classical model. Basically it's a bucket where you put your data, shared between the controller and the view.
    2. Angular performs Dependency Injection by inspecting your function parameter names and attempting to map them to known components. While a :wtf:, this is not a recommended development pattern, there are better ways to inject your dependencies (why does a tutorial teach this then…).
      Naming your function parameter $scope gives you your scope (which will also be used by your view), naming a parameter phoneDialer will give you an instance of a component named phoneDialer, etc.
    3. In inject(function($controller)... , the $controller is the factory that instantiates your controller and injects its dependencies, using both the dependencies you list and other components you have in your app. This way, if you pass additional info in the second argument ({$scope: scope} object in this test), you can mock any additional dependencies your controller has.
      So "scope" is the right way to provide data from the controller to the outside world, and it does rely on these magic names.


  • @dcoder

    @dcoder said in AngularJS scope in unit test:

    Are you sure you want to learn an old version of Angular? Is there an actual reason to do so (e.g. you need to support an existing application written in it, or you are interested in updating Cobolno longer popular projects)?

    1. I'm familiar with Angular 2. This is something that I would probably use for a hobby project.

    2. AngularJS > Angular 2 in terms of Adoption and Employment opportunities around here. This is primarily due to the fact that Angularjs can be integrated with existing web apps where Angular 2 is meant to be run as its own application if that makes any sense.

    I am also curious about ReactJs. I'm giving it a shot next. I'm tired of not knowing what all the hype is about.



  • @dcoder said in AngularJS scope in unit test:

    Stop what you are doing.

    Haha why would you think someone would try to learn something that uses JavaScript on purpose when there is something better unless there were reaaaaaaally good raisins



  • @dcoder said in AngularJS scope in unit test:

    Don't get confused by $ in these names. This is just some kind of convention, they could have named it "foo", it would have worked the same.

    That's not entirely right (but it may work correctly in the test nonetheless).

    I meant in terms of javascript in general.

    Javascript beginners sometimes think jQuery's $ object is somehow "magical" or "special". I vaguely remember maybe thinking the same thing at some point when I was starting out.

    I was just pointing out that "$" doesn't have any special meaning. That just happens to be the one non-alphanumeric character you can use in variables, so it's often used by frameworks to denote their special things.



  • @stillwater said in AngularJS scope in unit test:

    Are you sure you want to learn an old version of Angular? Is there an actual reason to do so (e.g. you need to support an existing application written in it, or you are interested in updating Cobolno longer popular projects)?

    I'm familiar with Angular 2. This is something that I would probably use for a hobby project.

    AngularJS > Angular 2 in terms of Adoption and Employment opportunities around here. This is primarily due to the fact that Angularjs can be integrated with existing web apps where Angular 2 is meant to be run as its own application if that makes any sense.

    Vue.js will be angular's successor on that front. It's the most lightweight of the big three and the easiest to just plug into an existing app (no special build system required).

    BTW, I agree with @DCoder. Angular 1 is no longer being maintained. Any job opportunities you are seeing now is pure inertia.

    Also, most job ads that I see for ang1 are sure to mention that knowledge any other SPA framework is a plus. It's clear business will be trying to migrate to something else and are looking for employees that can straddle the gap.

    So, learn angular 1 if you must to get the job, but also learn react or angular2 or vue, because that's where the future is.



  • @cartman82 said in AngularJS scope in unit test:

    Also, most job ads that I see for ang1 are sure to mention that knowledge any other SPA framework is a plus. It's clear business will be trying to migrate to something else and are looking for employees that can straddle the gap.

    Agreed.

    @cartman82 said in AngularJS scope in unit test:

    So, learn angular 1 if you must to get the job, but also learn react or angular2 or vue, because that's where the future is.

    I don't have a clue about the frontend framework world. I have very limited time to add one frontend framework to my toolkit. Would you recommend vue.js or react ?

    I just want something that gets shit done. I don't wanna generate 12003910390 files and run npm install npm magic npm fuckmeup blah blah blah and spend a whole day to print hello world.



  • @stillwater said in AngularJS scope in unit test:

    I don't have a clue about the frontend framework world. I have very limited time to add one frontend framework to my toolkit. Would you recommend vue.js or react ?
    I just want something that gets shit done. I don't wanna generate 12003910390 files and run npm install npm magic npm fuckmeup blah blah blah and spend a whole day to print hello world.

    Hmm, vue is the closest one to your "no build system, just get going" preference. It's main stronghold is Laravel community, which focuses on small to medium sized e-commerce-ish websites and startups. Also, a lot of Asian companies seem to like it, for some reason. Keep in mind that in any serious application you'd use vue with a build system anyway, so it's a wash on that front.

    React is beloved in startups and more hipsterish companies, especially those that want to have both the web and mobile apps (because of the excellent react-native). From a programming perspective, it's the one that I like the most. It goes the furthest towards putting the HTML and CSS parts of web development in a cage, so to speak, and just programming web apps using pure javascript. Depends whether you'd like that sort of thing or not.

    Angular 2 is very formulaic and strong typing based, which is preferred by enterprises for their internal apps. Very often used in combination with Microsoft's stack, as TypeScript is an easy transition for developers used to C#.

    I'd say all 3 frameworks are about equal in terms of technical merits, they all have their good sides and bad sides. Best look into the kind of companies that you want to get hired by and see what they are using. Then pick that.



  • @cartman82 I'm going with React if it helps with mobile apps too. Two birds, One stone something something. I'm excited as fuck. Thank you for the comprehensive answer good sir.



  • @stillwater said in AngularJS scope in unit test:

    I don't have a clue about the frontend framework world. I have very limited time to add one frontend framework to my toolkit. Would you recommend vue.js or react ?

    I just want something that gets shit done. I don't wanna generate 12003910390 files and run npm install npm magic npm fuckmeup blah blah blah and spend a whole day to print hello world.

    What @cartman82 said.

    Personally, I like React and TypeScript, I dislike Angular, and I haven't experimented with Vue enough to know if I like it. Just keep in mind that Angular is a full application framework - it has routers, controllers, models, views, services, and the KitchenSinkFactoryProvider, whereas React and Vue are view/templating libraries - you need extra libraries to provide routing, controllers, and other components. This is where things get complicated, and the React camp starts throwing around fancy terms like reducers and sagas. If you go with React/Vue, I would strongly suggest staying away from Redux/Vuex at first – build something with pure React/Vue, get familiar with their weaknesses, then look into Redux/Vuex to see how they can help.


  • Notification Spam Recipient

    @stillwater said in AngularJS scope in unit test:

    I'm excited as fuck

    Do you need help cleaning that up?


Log in to reply