Inject service into directive - angularjs

Cant inject the comment service into comment directive getting errorComment service not found
// Code goes here
var noBlogApp = angular.module("noBlogApp", ['ngRoute', 'ngSanitize', 'commentSystem']);
noBlogApp.config(['routeProvider', function(routeProvider) {
routeProvider.null when('/', {
controller: "noBlogController", null templateUrl: 'post.html',
}).when('/post/:id', {
controller: 'singlePostController',
templateUrl: 'singlepost.html',
});
}]);
noBlogApp.service('commentService', ['http', function(http) {
http.get('js/assureBlog.JSON').success(function(data) {
this.getComment = function(id) {
scope.comment = data[id];
return scope.comment;
}
var addComment = function() {
}
var addReply = function() {
}
var deleteComment = function() {
}
var deleteReply = function() {
}
});
}]);
noBlogApp.controller('noBlogController', ['scope', 'http', function(scope, http) {
scope.message = "hello";
http.get('js/assureBlog.JSON').success(function(data) {
scope.post = data;
});
}]);
nullnoBlogApp.controller('singlePostController', ['scope', 'http', 'routeParams', 'commentService', function(scope, http, routeParams, commentService) {
null http.get('js/assureBlog.JSON').success(function(data) {
scope.post = data[routeParams.id];
});
scope.commentService = commentService;
console.log("this is the" + commentService) null
}]);
noBlogApp.directive('comments', ["commentService", function(commentService) {
return {
scope: {
id: '#'
},
template: id: {
{
id
}
}
link: function(scope, element, attrs, commentService) {
console.log(scope.commentService);
}
};
}]);

Although the question is poorly formatted, it looks like your issue is this:
link:function(scope,element,attrs,commentService)
Remove the commentService from the link function. You've already added the dependency to the directive construction.

Related

AngularJS Directive data binding not happening from controller

I am facing the problem of data binding from controller to directive because of delay in response from the server.
To better understand just see a small program below.When I remove the timeout function, binding happens.
<msg track="{{customer}}"></msg>
angular.module('myApp').directive('msg', function() {
return {
scope: {
track :"#"
},
link : function(scope, element, attrs) {
},
template : "<a href>{{track}}</a>"
}
});
angular.module('myApp').controller('HomeCtrl', ['$scope', function($scope) {
setTimeout(function() {
$scope.customer = "shreyansh";
}, 5000);
// assume some service call inside controller
// service1.getData().then(function(data){$scope.customer = data})
}]);
How can i fix above problem so that above code should render as
<msg track="shreyansh" class="ng-isolate-scope">shreyansh</msg>.
Any help is appreciated.
Thanks
var app = angular.module('plunker', []);
app.factory('myService', function($http) {
var promise;
var myService = {
getData: function() {
if (!promise) {
promise = $http.get('test.json').then(function(response) {
return response.data;
});
}
return promise;
}
};
return myService;
});
app.controller('MainCtrl', function(myService, $scope) {
myService.getData().then(function(d) {
$scope.data = d;
});
});
app.directive('msg', function() {
return {
restrict: 'E',
scope: {
track: "#"
},
link: function(scope, element, attrs) {
},
template: "<a href>{{track}}</a>"
}
});
<msg track="{{data.name}}"></msg>
test.json file
{
"name": "Pete"
}

Unit Testing a watch method call in Directive link function

I have the following Directive
.directive("myContainer", function (myContainerService,$window) {
return {
restrict: 'A',
templateUrl: "myContainer/MyContainer.tpl.html",
controller: 'myCtrl',
controllerAs: 'myCtrl',
scope: {
items: '='
},
link: function (scope, element) {
var timeout;
scope.$watch('myCtrl.items', function (items) {
var windowWidth = $window.innerWidth - 65;
window.clearTimeout(timeout);
timeout = window.setTimeout(function () {
myContainerService.saveItems(items);
}, 1000);
}, true);
}
};
})
And here is the Unit Test i have.
describe("myCtrl", function(){
var myCtrl;
var dirEle ;
var myScope;
// var to store the Mock Items
var myContainerService = $injector.get('myContainerService');
var items = [..]
beforeEach(inject(function($compile, $httpBackend){
$httpBackend.whenGET(/.*my-app\/restful-services\/items*./).respond({...});
scope.items = myContainerService.getItems();
dirEle = $compile('<div my-container items="items"></div>')(scope);
scope.$digest();
myScope = dirEle.isolateScope();
myCtrl = myScope.myCtrl;
}));
fit("Saving Items", inject(function($timeout){
spyOn(myContainerService, 'saveItems');
//$timeout.flush();
myScope.$digest();
$timeout.flush();
expect(myContainerService.saveItems).toHaveBeenCalledWith(myCtrl.items);
}));
});
And my test is failing as the saveItems is not getting called at all. Not sure what i am doing wrong.
Appreciate any inputs.
Thanks
You need to be using angulars $timeout that way in your test your $timeout.flush() will work:
.directive("myContainer", function (myContainerService,$window, $timeout) {
return {
restrict: 'A',
templateUrl: "myContainer/MyContainer.tpl.html",
controller: 'myCtrl',
controllerAs: 'myCtrl',
scope: {
items: '='
},
link: function (scope, element) {
var timeout;
scope.$watch('myCtrl.items', function (items) {
var windowWidth = $window.innerWidth - 65;
$timeout.cancel(timeout);
timeout = $timeout(function () {
myContainerService.saveItems(items);
}, 1000);
}, true);
}
};
})

accessing controller from a seperate directive causing unexpected erros

I am following the joe eames tutorials on pluralsight. It seems to be fairly straightforward. I am setting up one directive inside of another, and setting up * require: on a child controller*
Here is the code that I have from the demo. I am using angular 1.5 I haven't changed the $scope to controllerAs as I am focused on figuring out communication between directive controllers.
(function() {
'use strict';
angular
.module('app', [])
.controller('mainCtrl', function($scope) {
})
.directive('swTabstrip', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: function($scope) {
$scope.panes = [];
$scope.select = function(pane) {
pane.selected = true;
$scope.panes.forEach(function(curPane) {
if(curPane !== pane) {
curPane.selected = false;
}
})
}
this.addPane = function(pane) {
$scope.panes.push(pane);
if($scope.panes.length ===1) {
pane.selected = true;
}
}
},
templateUrl: 'swTabstrip.html'
}
})
.directive('swPane', function() {
return {
restrict: 'E',
transclude: true,
scope: {
title: '#'
},
require: '^swTabstrip',
link: function(scope, el, attrs, tabstripCtrl) {
tabstripCtrl.addPane(scope);
},
templateUrl: 'swPane.html'
}
})
})();
The tutorial calls for me to set up directive swPane to require 'swTabstrip'. However, I am getting an error in the console
3angular.js:13156 Error: [$compile:ctreq]
Controller 'swTabstrip', required by directive 'swPane', can't be found!
You have to actually create your tabstripCtrl that your directive uses and at the same time then you can pass it in:
(function () {
'use strict';
angular
.module('app', [])
.controller('mainCtrl', function ($scope) {})
.controller('tabstripCtrl', function($scope) {
$scope.panes = [];
$scope.select = function (pane) {
pane.selected = true;
$scope.panes.forEach(function (curPane) {
if (curPane !== pane) {
curPane.selected = false;
}
})
}
this.addPane = function (pane) {
$scope.panes.push(pane);
if ($scope.panes.length === 1) {
pane.selected = true;
}
}
})
.directive('swTabstrip', function () {
return {
restrict : 'E',
transclude : true,
scope : {},
controller : 'tabstripCtrl' ,
templateUrl : 'swTabstrip.html'
}
})
.directive('swPane', function () {
return {
restrict : 'E',
transclude : true,
scope : {
title : '#'
},
require : '^tabstripCtrl',
link : function (scope, el, attrs, tabstripCtrl) {
tabstripCtrl.addPane(scope);
},
templateUrl : 'swPane.html'
}
})
})();
If you are trying to share data between your directives, look into services.

Angular directive not rendering scope values in view

My directive uses a service which returns a promise, I need to display the scope attributes geoZip, geoCity and geoState in the template.
The issue is that those scope variables are not being shown in the template, I just see the comma.
What should I do to make it display the scope variables?
This is my directive code:
.directive('cityStateZip', function() {
return {
restrict: 'A',
transclude: true,
scope: {
zip: '=',
},
template: '<p>{{geoCity}}, {{geoState}} {{geoZip}}</p>',
controller: ['$scope', 'GeolocationService', function ($scope, GeolocationService) {
GeolocationService.geocode($scope.zip).then(function(result) {
if (result) {
console.log(result);
$scope.geoZip = result['address_components'][0]['long_name'];
$scope.geoCity = result['address_components'][1]['long_name'];
$scope.geoState = result['address_components'][2]['short_name'];
}
});
}]
};
})
.service('GeolocationService', ['underscore', '$q', function (underscore, $q) {
var gs = {};
gs.geocode = function(address) {
var geocoder = new google.maps.Geocoder();
var deferred = $q.defer();
geocoder.geocode( { "address": address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
return deferred.resolve(underscore.first(results));
}
return deferred.reject();
});
return deferred.promise;
}
return gs;
}]);
I found that I have to use the $timeout service to make it work:
.directive('cityStateZip', function() {
return {
restrict: 'A',
transclude: true,
scope: {
zip: '=',
},
template: '<p>{{geoCity}}, {{geoState}} {{geoZip}}</p>',
controller: ['$scope', '$timeout', 'GeolocationService', function ($scope, $timeout, GeolocationService) {
GeolocationService.geocode($scope.zip).then(function(result) {
if (result) {
console.log(result);
$timeout(function() {
$scope.geoZip = result['address_components'][0]['long_name'];
$scope.geoCity = result['address_components'][1]['long_name'];
$scope.geoState = result['address_components'][2]['short_name'];
});
}
});
}]
};
})
Please let me know if there is best alternative (not using $timeout), Thanks!

How to make function to be fired when directive loaded?

I define this directive:
(function () {
"use strict";
angular.module("inspectionReview").directive("inspectionsReviewsList", ["config",inspectionsReviewsList]);
function inspectionsReviewsList(config) {
var directive = {
restrict: "E",
scope: {
objectId: "=",
region: "="
},
templateUrl: config.baseUrl + "app/InspectionReview/templates/inspectionsReviewsList.templ.html",
controller: "inspectionsReviewsListController",
controllerAs: "list"
}
return directive;
}
angular.module("inspectionReview").controller("inspectionsReviewsListController", ["$scope",
"$uibModal",
"inspectionReviewServices",
"toaster",
inspectionsReviewsListController]);
function inspectionsReviewsListController($scope, $uibModal, inspectionReviewServices, toaster) {
//===============================check status of site object================================
$scope.$watch('inspectionReviews', function () {
_.each($scope.inspectionReviews, function (value, key) {
if (!value.IsNormal) {
return $scope.status = false;
}
$scope.status = true;
})
}, true)
//===================================modal window============================================
$scope.open = function (size) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'app/siteObjects/templates/myModalContent.tmpl.html',
controller: 'myModalWindowController',
size: 'sm',
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
//$log.info('Modal dismissed at: ' + new Date());
});
};
}
})();
In the view:
<inspections-reviews-list id="object.Id"></inspections-reviews-list>
How can I make this function:
inspectionReviewServices.getValues(objectId).then(function (result) {
$scope.inspectionReviews = result.data;
});
to be fired when when directive is loaded.
You can assign a function to the directive's link property, as follows:
link : getValues;
The getValues functions is like this:
function getValues(scope, element, attributes) {
inspectionReviewServices.getValues(attributes.id).then(function (result) {
scope.inspectionReviews = result.data;
});
}
use like this... it will work..
function () {
angular.module("inspectionReview").directive("inspectionsReviewsList", ["config",inspectionsReviewsList]);
function inspectionsReviewsList(config) {
var directive = {
restrict: "E",
scope: {
objectId: "=",
region: "="
},
link : function getValues(scope, element, attributes) {
inspectionReviewServices.getValues(attributes.id).then(function (result) {
scope.inspectionReviews = result.data;
});
},
templateUrl: config.baseUrl + "app/InspectionReview/templates/inspectionsReviewsList.templ.html",
controller: "inspectionsReviewsListController",
controllerAs: "list"
}
return directive;
}

Resources