AngularJS interview questions

AngularJS quiz questions

  • 1.

    How would you make an Angular service return a promise? Write a code snippet as an example

    Answer:

    To add promise functionality to a service, we inject the “$q” dependency in the service, and then use it like so:

    angular.factory('testService', function($q){
    	return {
    		getName: function(){
    			var deferred = $q.defer();
    
    			//API call here that returns data
    			testAPI.getName().then(function(name){
    				deferred.resolve(name)
    			})
    
    			return deferred.promise;
    		}
    	}
    })

    The $q library is a helper provider that implements promises and deferred objects to enable asynchronous functionality

    Source: https://docs.angularjs.org/api/ng/service/$q

    View
  • 2.

    What makes the angular.copy() method so powerful?

    Answer:

    It creates a deep copy of the variable.

    A deep copy of a variable means it doesn’t point to the same memory reference as that variable. Usually assigning one variable to another creates a “shallow copy”, which makes the two variables point to the same memory reference. Therefore if we change one, the other changes as well

    Sources:
    – https://docs.angularjs.org/api/ng/function/angular.copy
    – https://en.wikipedia.org/wiki/Object_copying

    View
  • 3.

    What directive would you use to hide elements from the HTML DOM by removing them from that DOM not changing their styling?

    Answer:

    The ngIf Directive, when applied to an element, will remove that element from the DOM if it’s condition is false.

    View
  • 4.

    Explain how $scope.$apply() works

    Answer:

    $scope.$apply re-evaluates all the declared ng-models and applies the change to any that have been altered (i.e. assigned to a new value)
    Explanation: $scope.$apply() is one of the core angular functions that should never be used explicitly, it forces the angular engine to run on all the watched variables and all external variables and apply the changes on their values
    Source: https://docs.angularjs.org/api/ng/type/$rootScope.Scope

    View
  • 5.

    What is the difference between one-way binding and two-way binding?

    Answer:

    – One way binding implies that the scope variable in the html will be set to the first value its model is bound to (i.e. assigned to)
    – Two way binding implies that the scope variable will change it’s value everytime its model is assigned to a different value

    View
  • 6.

    How would you specify that a scope variable should have one-time binding only?

    Answer:

    By using “::” in front of it. This allows the check if the candidate is aware of the available variable bindings in AngularJS.

    View
  • 7.

    If you were to migrate from Angular 1.4 to Angular 1.5, what is the main thing that would need refactoring?

    Answer:

    Changing .directive to .component to adapt to the new Angular 1.5 components

    View
  • 8.

    Is it a good or bad practice to use AngularJS together with jQuery?

    Answer:

    It is definitely a bad practice. We need to stay away from jQuery and try to realize the solution with an AngularJS approach. jQuery takes a traditional imperative approach to manipulating the DOM, and in an imperative approach, it is up to the programmer to express the individual steps leading up to the desired outcome.

    AngularJS, however, takes a declarative approach to DOM manipulation. Here, instead of worrying about all of the step by step details regarding how to do the desired outcome, we are just declaring what we want and AngularJS worries about the rest, taking care of everything for us.
    Here is a detailed explanation

    View
  • 9.

    Where should we implement the DOM manipulation in AngularJS?

    Answer:

    In the directives. DOM Manipulations should not exist in controllers, services or anywhere else but in directives.

    Here is a detailed explanation

    View
  • 10.

    What is a digest cycle in AngularJS?

    Answer:

    In each digest cycle Angular compares the old and the new version of the scope model values. The digest cycle is triggered automatically. We can also use $apply() if we want to trigger the digest cycle manually.

    For more information, take a look in the ng-book explanation: The Digest Loop and $apply

    View
  • 11.

    What is the difference between ng-show/ng-hide and ng-if directives?

    Answer:

    ng-show/ng-hide will always insert the DOM element, but will display/hide it based on the condition. ng-if will not insert the DOM element until the condition is not fulfilled.

    ng-if is better when we needed the DOM to be loaded conditionally, as it will help load page bit faster compared to ng-show/ng-hide.

    We only need to keep in mind what the difference between these directives is, so deciding which one to use totally depends on the task requirements.

    View
  • 12.

    How do you share data between controllers?

    Answer:

    Create an AngularJS service that will hold the data and inject it inside of the controllers.

    Using a service is the cleanest, fastest and easiest way to test.
    However, there are couple of other ways to implement data sharing between controllers, like:
    – Using events
    – Using $parentnextSiblingcontrollerAs, etc. to directly access the controllers
    – Using the $rootScope to add the data on (not a good practice)
    The methods above are all correct, but are not the most efficient and easy to test.
    Here is a good video explanation on egghead.io.

    View
  • 13.

    What should be the maximum number of concurrent “watches”? Bonus: How would you keep an eye on that number?

    Answer:

    TL;DR Summary: To reduce memory consumption and improve performance it is a good idea to limit the number of watches on a page to 2,000. A utility called ng-stats can help track your watch count and digest cycles.

    Jank happens when your application cannot keep up with the screen refresh rate. To achieve 60 frames-per-second, you only have about 16 milliseconds for your code to execute. It is crucial that the scope digest cycles are as short as possible for your application to be responsive and smooth. Memory use and digest cycle performance are directly affected by the number of active watches. Therefore, it is best to keep the number of watches below 2,000. The open-source utility ng-stats gives developers insight into the number of watches Angular is managing, as well as the frequency and duration of digest cycles over time.

    Caution: Be wary of relying on a “single magic metric” as the golden rule to follow. You must take the context of your application into account. The number of watches is simply a basic health signal. If you have many thousands of watches, or worse, if you see that number continue to grow as you interact with your page. Those are strong indications that you should look under the hood and review your code.

    This question is valuable as it gives insight into how the candidate debugs runtime issues while creating a discussion about performance and optimization.

    View
  • 14.

    What are the basic steps to unit test an AngularJS filter?

    Answer:

    1. Inject the module that contains the filter.
    2. Provide any mocks that the filter relies on.
    3. Get an instance of the filter using $filter('yourFilterName').
    4. Assert your expectations.

    Dependency injection is a powerful software design pattern that Angular employs to compose responsibilities through an intrinsic interface. However, for those new to the process, it can be puzzling where you need to configure and mock these dependencies when creating your isolated unit tests. The open-source project “Angular Test Patterns” is a free resource that is focused on dispelling such confusion through high-quality examples.

    This question is useful since it can give you a feel for how familiar the candidate is with automated testing (TDD, BDD, E2E), as well as open up a conversation about approaches to code quality.

    View
  • 15.

    What is $rootScope and how does it relate to $scope?

    Answer:

    $rootScope is the parent object of all $scope Angular objects created in a web page.

    View
  • 16.

    List a few ways to improve performance in an AngularJS app.

    Answer:

    The two officially recommended methods for production are disabling debug data and enabling strict DI mode.

    The first one can be enabled through the $compileProvider:

    myApp.config(function ($compileProvider) {
      $compileProvider.debugInfoEnabled(false);
    });
    

    That tweak disables appending scope to elements, making scopes inaccessible from the console. The second one can be set as a directive:

    <html ng-app=“myApp” ng-strict-di>
    

    The performance gain lies in the fact that the injected modules are annotated explicitly, hence they don’t need to be discovered dynamically.

    You don’t need to annotate yourself, just use some automated build tool and library for that.

    Two other popular ways are:

    • Using one-time binding where possible. Those bindings are set, e.g. in “{{ ::someModel }}” interpolations by prefixing the model with two colons. In such a case, no watch is set and the model is ignored during digest.
    • Making $httpProvider use applyAsync:
    myApp.config(function ($httpProvider) {
      $httpProvider.useApplyAsync(true);
    });
    

    … which executes nearby digest calls just once, using a zero timeout.

    View
  • 17.

    How does the digest phase work?

    Answer:

    In a nutshell, on every digest cycle all scope models are compared against their previous values. That is dirty checking. If change is detected, the watches set on that model are fired. Then another digest cycle executes, and so on until all models are stable.

    It is probably important to mention that there is no “.$digest()” polling. That means that every time it is being called deliberately. As long as core directives are used, we don’t need to worry, but when external code changes models the digest cycle needs to be called manually. Usually to do that, “.$apply()” or similar is used, and not “.$digest()” directly.

    View
  • 18.

    How does interpolation, e.g. “{{ someModel }}”, actually work?

    Answer:

    It relies on $interpolation, a service which is called by the compiler. It evaluates text and markup which may contain AngularJS expressions. For every interpolated expression, a “watch()” is set. $interpolation returns a function, which has a single argument, “context”. By calling that function and providing a scope as context, the expressions are “$parse()”d against that scope.

    View
  • 19.

    Name and describe the phases of a directive definition function execution, or describe how directives are instantiated.

    Answer:

    The flow is as follows:

    First, the “$compile()” function is executed which returns two link functions, preLink and postLink. That function is executed for every directive, starting from parent, then child, then grandchild.

    Secondly, two functions are executed for every directive: the controller and the prelink function. The order of execution again starts with the parent element, then child, then grandchild, etc.

    The last function postLink is executed in the inverse order. That is, it is first executed for grandchild, then child, then parent.

    A great explanation of how directives are handled in AngularJS is available in the AngularJS Tutorial: Demystifying Custom Directives post on the Toptal blog.

    View
  • 20.

    How do you reset a “$timeout”, and disable a “$watch()”?

    Answer:

    The key to both is assigning the result of the function to a variable.

    To cleanup the timeout, just “.cancel()” it:

    var customTimeout = $timeout(function () {
      // arbitrary code
    }, 55);
    
    $timeout.cancel(customTimeout);
    

    The same applies to “$interval()”.

    To disable a watch, just call it.

    // .$watch() returns a deregistration function that we store to a variable
    var deregisterWatchFn = $rootScope.$watch(‘someGloballyAvailableProperty’, function (newVal) {
      if (newVal) {
        // we invoke that deregistration function, to disable the watch
        deregisterWatchFn();
        ...
      }
    });
    View

© 2017 QuizBucket.org