Mocking service when testing controller in Karma for angularjs - javascript

I am working on the Single Page Application with AngularJS project for the Treehouse Full Stack JavaScript TechDegree and I am trying to do unit tests on the controllers. To test the controllers that make api calls to the dataService I have to mock the dataService and I can not figure out how to do this correctly. I have read article after article on unit testing angular and I am so lost that I have no idea what to do next.
controllers.js:
(function() {
'use strict';
angular.module('app')
.controller('RecipesController', function(dataService,$location) {
const vm = this;
vm.init = () => {
vm.hidden = true;
dataService.getAllRecipes(function(response) {
vm.recipes = response.data;
vm.getCategories(response.data);
});
}
vm.selectCategory = (category) => {
if (category === null) {
vm.init();
} else {
dataService.getCategory(category,function(response) {
vm.recipes = response.data;
});
}
};
vm.getCategories = (data) => {
let categories = new Set();
for (let item of data) {
categories.add(item.category);
}
vm.categories = Array.from(categories);
};
vm.addRecipe = () => {
$location.path('/add');
}
vm.deleteRecipe = (recipe,$index) => {
vm.toDelete = recipe.name;
vm.hidden = false;
vm.deleteIt = () => {
vm.hidden = true;
dataService.deleteRecipe(recipe._id,function(response) {
vm.init();
});
}
}
vm.init();
})
.controller('RecipeDetailController', function($scope,dataService,$location) {
const vm = this;
const init = () => {
const path = $location.path();
if (path.includes("edit")) {
let id = path.slice(6);
dataService.getID(id,function(response) {
vm.recipe = response.data;
vm.title = response.data.name;
vm.editCategory = response.data.category;
});
} else if (path.includes("add")) {
vm.recipe = {
name: "",
description: "",
category: "",
prepTime: 0,
cookTime: 0,
ingredients: [
{
foodItem: "",
condition: "",
amount: ""
}
],
steps: [
{
description: ""
}
]
}
vm.title = 'Add New Recipe.'
}
dataService.getAllCategories(function (response) {
vm.categories = response.data;
let index = response.data.findIndex(item => item.name === $scope.editCategory);
if (index === -1) {
vm.initial = {"name": "Choose a Category"};
} else {
vm.initial = $scope.categories[index];
}
});
dataService.getAllFoodItems(function (response) {
vm.foods = response.data;
});
}
vm.addItem = (item) => {
if (item === 'ingredient') {
vm.recipe.ingredients.push({amount: "amount", condition: "condition", foodItem: ""});
} else if (item === 'step') {
vm.recipe.steps.push({description: "description"});
}
};
vm.deleteItem = (item,$index) => {
if (item === 'ingredient') {
vm.recipe.ingredients.splice($index,1);
} else if (item === 'step') {
vm.recipe.steps.splice($index,1);
}
}
vm.saveChanges = (recipe) => {
vm.errors = [];
const buildErrorArray = (errorArray) => {
for (let item of errorArray) {
vm.errors.push(item.userMessage);
}
}
const collectErrors = (response) => {
if (response.data.errors.category) { buildErrorArray(response.data.errors.category) }
if (response.data.errors.ingredients) { buildErrorArray(response.data.errors.ingredients) }
if (response.data.errors.name) { buildErrorArray(response.data.errors.name) }
if (response.data.errors.steps) { buildErrorArray(response.data.errors.steps) }
}
if (recipe._id) {
dataService.updateID(recipe,function(response) {
$location.path('/');
}, function(response) {
collectErrors(response)
});
} else {
dataService.addRecipe(recipe,function(response) {
$location.path('/');
}, function(response) {
collectErrors(response)
});
}
}
vm.cancelChanges = () => {
$location.path('/');
}
init();
});
}());
services.js:
(function() {
'use strict';
angular.module('app')
.service('dataService', function($http,errors,httpErrors) {
this.getAllRecipes = function (callback) {
$http.get('http://localhost:5000/api/recipes')
.then(callback,httpErrors.display('HTTP Error'))
.catch(errors.catch());
};
this.getAllCategories = function (callback) {
$http.get('http://localhost:5000/api/categories')
.then(callback,httpErrors.display('HTTP Error'))
.catch(errors.catch());
};
this.getAllFoodItems = function (callback) {
$http.get('http://localhost:5000/api/fooditems')
.then(callback,httpErrors.display('HTTP Error'))
.catch(errors.catch());
};
this.getCategory = function(category,callback) {
$http.get('http://localhost:5000/api/recipes?category=' + category)
.then(callback,httpErrors.display('HTTP Error'))
.catch(errors.catch());
};
this.getID = function (id,callback) {
$http.get('http://localhost:5000/api/recipes/' + id)
.then(callback,httpErrors.display('HTTP Error'))
.catch(errors.catch());
};
this.updateID = function (data,success,error) {
$http.put('http://localhost:5000/api/recipes/' + data._id, data)
.then(success,error).catch(errors.catch());
};
this.addRecipe = function (data,success,error) {
$http.post('http://localhost:5000/api/recipes', data)
.then(success,error).catch(errors.catch());
};
this.deleteRecipe = function (id,callback) {
$http.delete('http://localhost:5000/api/recipes/' + id)
.then(callback,httpErrors.display('HTTP Error'))
.catch(errors.catch());
};
});
}());
controllersSpec.js:
describe("Unit Testing Controllers", function() {
beforeEach(angular.mock.module('app'));
let $scope;
let getAllRecipesMock;
beforeEach(inject(function(_$controller_,_$rootScope_,$q) {
$controller = _$controller_;
$scope = _$rootScope_.$new();
getAllRecipesMock = {
getAllRecipes: function() {
var deferred = $q.defer();
deferred.resolve([{name: "recipename"}]);
return deferred.promise;
}
}
}));
it('has a test to test that tests are testing', function() {
expect(2 + 2).toEqual(4);
});
it('should have a RecipesController', function() {
const controller = $controller('RecipesController',{$scope:$scope});
expect(controller).toBeDefined();
});
it('should have a RecipeDetailController', function() {
const controller = $controller('RecipeDetailController',{$scope:$scope});
expect(controller).toBeDefined();
});
it('should call the getAllRecipes service and return response', inject(function() {
const controller = $controller('RecipesController',{$scope:$scope,dataService:getAllRecipesMock});
$scope.$digest();
expect(controller.recipes).toBe([{name: "recipename"}]);
}));
it('should remove duplicate categories', function() {
const controller = $controller('RecipesController',{$scope:$scope});
let data = [{'category':'dog'},{'category':'cat'},{'category':'horse'},{'category':'dog'},{'category':'cow'}];
controller.getCategories(data);
expect(controller.categories).toEqual(['dog','cat','horse','cow']);
});
it('should take you to the /add route when the addRecipe method is called', inject(function($location) {
const controller = $controller('RecipesController',{$scope:$scope});
controller.addRecipe();
expect($location.path()).toEqual('/add');
}));
});
This is the result I get when I run the tests:
Unit Testing Controllers
√has a test to test that tests are testing
√should have a RecipesController
√should have a RecipeDetailController
×should call the getAllRecipes service and return response
Expected undefined to be [ Object({ name: 'recipename' }) ].
at Object.<anonymous> (test/controllersSpec.js:38:32)
at Object.invoke (node_modules/angular/angular.js:4839:19)
at Object.WorkFn (node_modules/angular-mocks/angular-mocks.js:3155:20)
√should remove duplicate categories
√should take you to the /add route when the addRecipe method is called
Chrome 55.0.2883 (Windows 10 0.0.0): Executed 6 of 6 (1 FAILED) (0.235 secs / 0.084 secs)
TOTAL: 1 FAILED, 5 SUCCESS
1) should call the getAllRecipes service and return response
Unit Testing Controllers
Expected undefined to be [ Object({ name: 'recipename' }) ].
at Object.<anonymous> (test/controllersSpec.js:38:32)
at Object.invoke (node_modules/angular/angular.js:4839:19)
at Object.WorkFn (node_modules/angular-mocks/angular-mocks.js:3155:20)
EDIT
I decided to change the service to return a promise instead of a callback:
this.getAllRecipes = function () {
return $http.get('http://localhost:5000/api/recipes');
};
Then I changed the corresponding function in the controller:
vm.init = () => {
vm.hidden = true;
let allRecipes = dataService.getAllRecipes();
allRecipes.then(function(response) {
vm.recipes = response.data;
vm.getCategories(response.data);
},httpErrors.display('HTTP Error'))
.catch(errors.catch());
}
but I'm still getting
Expected undefined to be [ Object({ name: 'recipename' }) ].
Am I not implementing the promise correctly? Is there still something in my test that I'm missing?

You are currently mixing callbacks and promises.
The method getAllRecipes in the real service implementation takes a callback as an argument and executes it when the internal ajax call is done. The consumer of the method has no idea that the implementation uses promises internally.
The mock implementation of getAllRecipes however does not take or use a callback function but instead returns a promise.
You have in your controller:
dataService.getAllRecipes(function(response) {
vm.recipes = response.data;
vm.getCategories(response.data);
});
But with the mock implementation you would need:
dataService.getAllRecipes(function(response) {
vm.recipes = response.data;
vm.getCategories(response.data);
}).then(function (response) {
// Code
});
With your current implementation of getAllRecipes your mock could look like this:
getAllRecipesMock = {
getAllRecipes: function(callback) {
var response = {
data: [{
name: "recipename"
}]
};
callback(response);
}
};
Also note that unless you want to compare for reference equality, use toEqual instead of toBe:
expect(controller.recipes).toEqual([{
name: "recipename"
}]);
Demo: http://plnkr.co/edit/5BQBt4tTxohXEN0Drq3f?p=preview
An alternative is to change the service implementation to return a promise instead of using callbacks.

Related

Unable to retrieve object from constructor function when running Cypress

I'm trying to access my own JS module when running Cypress tests. I have defined my own module as...
cy.companies = function () {
const Company = function () {
this.id = 0;
this.name = "";
};
return {
Company: function () {
return Company;
}
};
}();
I have then modified \support\index.js to include this file...
import "../fixtures/provisioning/companies";
Then inside \support\commands.js I have added...
Cypress.Commands.add("createCompany", () => {
return new cy.companies.Company();
});
So that's the setup. I then consume it like this...
describe("...", () => {
beforeEach(function () {
const company = cy.createCompany();
console.log(company)
});
});
In the console I would expect to see...
{
id: 0,
name: ""
}
...but what I actually see is...
$Chainer {userInvocationStack: " at Context.eval (https://[...]/__cy…press\integration\[...].spec.js:54:22)", specWindow: Window, chainerId: "chainer2", firstCall: false, useInitialStack: false}
chainerId: "chainer2"
firstCall: false
...
Where have I gone wrong?
First issue is in your js module:
cy.companies = (function () {
const Company = function () {
this.id = 0;
this.name = name;
};
/* return {
Company: function () {
return Company;
}
}; */
return { Company };
})();
Second issue is due to the fact: cy commands are asynchronous and are queued to be run later, so you need to use .then
describe("...", () => {
beforeEach(function () {
// const company = cy.createCompany();
// console.log(company)
cy.createCompany().then((company) => {
cy.log(company);
console.log(company);
});
});
});

How to access to a function from world.js?

I'm trying to access to this.addScreenshotToReport from a function of world.js
This is the code I been trying to export the world.js:
module.exports = function() {
var worldPath = path.join(config.paths.root, '../support/world')
this.World = require(worldPath).World;
}
And i put this.addScreenshotToReport() to access in that specific tunction
This is the code from world.js:
function CustomWorld({attach, parameters}) {
this.waitForTestController = testControllerHolder.get()
.then(function(tc) {
return testController = tc;
});
this.attach = attach;
this.setBrowser = function() {
if (parameters.browser === undefined) {
return 'chrome';
} else {
return parameters.browser;
}
};
this.addScreenshotToReport = function() {
if (process.argv.includes('--format') || process.argv.includes('-f') || process.argv.includes('--format-options')) {
testController.takeScreenshot()
.then(function(screenshotPath) {
const imgInBase64 = base64Img.base64Sync(screenshotPath);
const imageConvertForCuc = imgInBase64.substring(imgInBase64.indexOf(',') + 1);
return attach(imageConvertForCuc, 'image/png');
})
.catch(function(error) {
console.warn('The screenshot was not attached to the report');
});
} else {
return new Promise((resolve) => {
resolve(null);
});
}
};
The actual output is:
TypeError: this.addScreenshotToReport is not a function

Unit Testing BelongsToMany relations in Sequelize using Jasmine

I'm building a simple blog style application for practice using Node and Sequelize (with the Yeoman angular-fullstack generator). I'm trying to write out some tests for my article model, but I'm unable to figure out the right way to structure my tests. The articles and users are connected by a two-way belongsToMany relationship.
I'm able to verify that the setter and getter methods exist for my objects, but am unable to verify that they work. The code I'm trying to get to work is the code commented out at the end of the file. I'd appreciate any help in getting that unit test to work correctly, thanks!
'use strict';
/* globals describe, expect, it, beforeEach, afterEach */
var app = require('../..');
import request from 'supertest';
import {User, Article} from '../../sqldb';
var user = [];
var article = [];
var genArticles = function(i) {
for(var i = 0; i < 3; i++) {
article[i] = genArticle(i);
}
return article;
}
var genUsers = function(i) {
for(var i = 0; i < 3; i++) {
user[i] = genUser(i);
}
return user;
}
var genUser = function(i) {
return User.build({
provider: 'local',
name: `Fake User ${i}`,
email: `test${i}#example.com`,
password: 'password'
});
};
var genArticle = function(i) {
return Article.build({
title: `Fake Article ${i}`,
body: `test${i}`
});
};
describe("Article-User relations", function() {
before(function() {
return User.sync().then(function() {
return User.destroy({ where: {} }).then(function() {
return Article.sync().then(function() {
return Article.destroy({ where: {} }).then(function() {
});
});
});
});
});
beforeEach(function(done) {
genArticles();
genUsers();
done();
});
afterEach(function() {
return User.sync().then(function() {
return User.destroy({ where: {} }).then(function() {
return Article.sync().then(function() {
return Article.destroy({ where: {} }).then(function() {
});
});
});
});
});
it('should begin with no data', function() {
expect(User.findAll()).to
.eventually.have.length(0);
return expect(Article.findAll()).to
.eventually.have.length(0);
});
describe("Check methods exist and", function(done) {
before(function(done) {
article.forEach((a) => {a.save()});
user.forEach((a) => {a.save()});
done();
});
it("should have setter methods", function() {
expect(typeof article[0].setUsers).to.equal("function");
expect(typeof user[0].setArticles).to.equal("function");
});
it("should have getter methods", function() {
expect(typeof article[0].getUsers).to.equal("function");
expect(typeof user[0].getArticles).to.equal("function");
});
/* THIS IS THE TEST THAT ISN'T WORKING */
/*
it("setter and getter methods for article objects should work", function() {
return article[0].setUsers(user).then(() => {
return article[0].hasUsers(user).then( result => {
expect(result).should.eventually.equal.true;
})
}).catch( e => { console.log(e) });
//expect(typeof user[0].setArticles).to.equal("function");
});
*/
});
});

How test Service working with IndexedDB in AngularJS

I have app in AngularJS, where I make services, which stores data to IndexedDb.
It's look like this:
var IndexedDbServices = angular.module('IndexedDbServices', []);
IndexedDbServices.factory('IndexedDb', ['$window', '$q', function($window, $q){
var indexedDB = $window.indexedDB;
var db=null;
var open = function() {
var deferred = $q.defer();
var version = 3;
var request = indexedDB.open("lCApp", version);
request.onupgradeneeded = function(e) {
db = e.target.result;
e.target.transaction.onerror = indexedDB.onerror;
if(db.objectStoreNames.contains("collections")) {
db.deleteObjectStore("collections");
}
var store = db.createObjectStore("collections", {
keyPath: "id", autoIncrement : true
});
store.createIndex("name", "name", { unique: true });
store.createIndex("description", "description", { unique: false });
store.transaction.oncomplete = function(event) {
var customerObjectStore = db.transaction("collections", "readwrite").objectStore("collections");
customerObjectStore.add({name: "coll1", description: "desc for coll1"});
customerObjectStore.add({name: "coll2", description: "desc for coll2"});
};
};
request.onsuccess = function(e) {
db = e.target.result;
deferred.resolve();
};
request.onerror = function(){
deferred.reject();
};
return deferred.promise;
};
var findAll = function() {
var deferred = $q.defer();
if(db === null || db === undefined) {
deferred.reject("IndexDB is not opened yet!");
} else{
var trans = db.transaction(["collections"], "readwrite");
var store = trans.objectStore("collections");
var data = [];
// Get everything in the store;
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(result === null || result === undefined)
{
deferred.resolve(data);
}
else{
data.push(result.value);
result.continue();
}
};
cursorRequest.onerror = function(e){
console.log(e.value);
deferred.reject("Something went wrong!!!");
};
}
return deferred.promise;
};
return {
open: open,
add: add,
findAll: findAll
};
}]);
And I want test this code using unit test (jasmine). So i wrote this:
describe('IndexedDB service', function() {
beforeEach(function() {
module('IndexedDbServices');
});
it('should open db and find 2 collections', inject(function(IndexedDb) {
IndexedDb.open().then(function(e){
console.log(e);
}, function(err){
$window.alert(err);
});
console.log(IndexedDb.findAll());
}));
});
Would you advise me how test if function open in IndexedDb service create IndexedDb and add rows. And next I function open in IndexedDB service return all that records?
I don't know why, but in this test db is not created console.log(IndexedDb.findAll()); print: Promise{$$state: Object{status: 2, value: 'IndexDB is not opened yet!'}}
So Db is not created.
And next how use expect(..).toEqual() or something this in returned promises?
Let's have the service:
/*global window: false */
'use strict';
angular.module('main')
.config(['$provide', function ($provide) {
$provide.constant('indexedDB', window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB);
}])
.service('idb', function idbService($q, $rootScope, indexedDB) {
var service = this;
var db;
service.open = function () {
console.log('idb.open');
var deferred = $q.defer();
var request = indexedDB.open('mydb', 1);
request.onupgradeneeded = function (e) {
console.log('idb.open onupgradeneeded');
db = e.target.result;
if (!db.objectStoreNames.contains('mystore')) {
db.createObjectStore('mystore', {
keyPath: 'id'
});
}
};
request.onsuccess = function (e) {
console.log('idb.open onsuccess');
db = e.target.result;
deferred.resolve();
$rootScope.$apply(); // Propagate promise resolution to 'then' functions using $apply().
};
request.onerror = function (e) {
console.log('idb.open onerror ', e);
deferred.reject();
};
return deferred.promise;
};
service.put = function (key, value) {
console.log('idb.put(' + key + ', ' + value + ')');
var deferred = $q.defer();
var store = db.transaction(['mystore'], 'readwrite').objectStore('mystore');
var request = store.put({
id: key,
data: value
});
request.onsuccess = function () {
console.log('idb.put onsuccess');
deferred.resolve();
$rootScope.$apply(); // Propagate promise resolution to 'then' functions using $apply().
};
request.onerror = function (e) {
console.log('idb.put onerror ', e);
deferred.reject(e);
};
return deferred.promise;
};
service.get = function (key) {
console.log('idb.get' + '(' + key + ')');
var deferred = $q.defer();
var store = db.transaction(['mystore'], 'readwrite').objectStore('mystore');
var request = store.get(key);
request.onsuccess = function (e) {
console.log('idb.get onsuccess ', e.target.result);
deferred.resolve(e.target.result.data);
$rootScope.$apply(); // Propagate promise resolution to 'then' functions using $apply().
};
request.onerror = function (e) {
console.log('idb.get onerror', e);
deferred.reject(e);
};
return deferred.promise;
};
});
Test can be:
'use strict';
describe('idb', function () {
beforeEach(module('main'));
var idb;
var idbOpened;
beforeEach(angular.mock.inject(function (_idb_) {
idb = _idb_;
}));
beforeEach(function (done) {
idbOpened = false;
console.log(1);
idb.open().then(function () {
console.log(3);
idbOpened = true;
done();
})
console.log(2);
});
it('opens', function () {
expect(idbOpened).toBe(true);
console.log(4);
});
it('gets the put', function (done) {
console.log(10);
idb.put('666', 'bob').then(function () {
console.log(12);
idb.get('666').then(function (value) {
console.log(13);
expect(value).toBe('bob');
done();
console.log(14);
})
})
console.log(11);
});
});
Test output would be then:
LOG: 1
LOG: 'idb.open'
LOG: 2
LOG: 'idb.open onsuccess'
LOG: 3
LOG: 4
LOG: 1
LOG: 'idb.open'
LOG: 2
LOG: 'idb.open onsuccess'
LOG: 3
LOG: 10
LOG: 'idb.put(666, bob)'
LOG: 11
LOG: 'idb.put onsuccess'
LOG: 12
LOG: 'idb.get(666)'
LOG: 'idb.get onsuccess ', Object{id: '666', data: 'bob'}
LOG: 13
LOG: 14
Ugly stuff is a need to call
$rootScope.$apply();
to propagate promise resolution to 'then' functions in the test, because
it is not needed for the service itself.

API calls in angularJS right after each other

I have a problem using angular in a Ionic mobile project , I have this piece of code working great in my desktop environment. I do three API call to a web server 500ms after each other. But in the phone using a lower connection sometimes one of the call fails so the whole process fail.
Is there some way to do the API calls in the exact moment that the previous one finish? I mean, not using fixed amount of time.
//get member information
$timeout(function() {
membersService.getMember(community.url, community.user.api_key, community.user.auth_token, $stateParams.userId).
success(function(data) {
$scope.member = data.result;
});
}, 500);
$timeout(function() {
messagesService.getConversation(community.url, community.user.api_key, community.user.auth_token, community.user.user_info.guid, $stateParams.userId, "from").
success(function(data) {
if(data.result["entities"].length > 0) {
messages = messages.concat(data.result["entities"]);
subject = "Re: "+data.result["entities"][data.result["entities"].length-1].title;
}
$scope.messageData.subject = subject;
});
}, 1000);
$timeout(function() {
messagesService.getConversation(community.url, community.user.api_key, community.user.auth_token, community.user.user_info.guid, $stateParams.userId, "to").
success(function(data) {
log = [];
if(data.result["entities"].length > 0) {
angular.forEach(data.result["entities"], function(v, k) {
v.owner_guid = $stateParams.userId;
log.push(v);
}, log);
messages = messages.concat(log);
}
var log = [];
var count = 0;
angular.forEach(messages, function(v, k) {
messages_reorder.push(v);
}, log);
});
}, 1500);
This was the result of implementing nesting promise chains:
var loadMemberInfo = function( userId )
{
return membersService
.getMember(community.url, community.user.api_key, community.user.auth_token, $stateParams.userId)
.then(function(data)
{
$scope.member = data.result;
});
},
getConversationFrom = function() {
return messagesService
.getConversation(community.url, community.user.api_key, community.user.auth_token, community.user.user_info.guid, $stateParams.userId, "from")
.then(function(cf) {
if(cf.data.result["entities"].length > 0) {
messages = messages.concat(cf.data.result["entities"]);
subject = "Re: "+cf.data.result["entities"][cf.data.result["entities"].length-1].title;
}
$scope.messageData.subject = subject;
});
},
getConversationTo = function() {
messagesService
.getConversation(community.url, community.user.api_key, community.user.auth_token, community.user.user_info.guid, $stateParams.userId, "to")
.then(function(ct) {
log = [];
if(ct.data.result["entities"].length > 0) {
angular.forEach(ct.data.result["entities"], function(v, k) {
v.owner_guid = $stateParams.userId;
log.push(v);
}, log);
messages = messages.concat(log);
}
//order array
messages = messages.sort(function(a,b) { return a.time_created - b.time_created } );
var log = [];
var count = 0;
angular.forEach(messages, function(v, k) {
messages_reorder.push(v);
}, log);
});
},
orderFullConversation = function() {
$ionicLoading.hide();
console.log(messages);
if(messages_reorder.length > 5) {
var messages_partial = messages_reorder.slice(messages_reorder.length-5,messages_reorder.length);
}
else {
var messages_partial = messages_reorder;
}
$scope.messages = messages_partial;
$scope.community = community;
};
loadMemberInfo( $stateParams.userId )
.then( getConversationFrom )
.then( getConversationTo )
.then( orderFullConversation );
More details here
You can use angular $q service for that.
You should look at the Angular Promise API. it is meant for the same purpose. It allows you to chain ajax calls one after another..
// this
$http.get('/api/v1/movies/avengers')
.success(function(data, status, headers, config) {
$scope.movieContent = data;
});
// is the same as
var promise = $http.get('/api/v1/movies/avengers');
promise.then(
function(payload) {
$scope.movieContent = payload.data;
});
More Details here

Categories

Resources