This is a simple service I created:
var app = angular.module('myApp', ['ngRoute']);
app.service('UserService', function() {
this.user = {firstName:"",middleName:"",lastName:"",email:"",dob:""};
this.addUser = function (user) {
users.push(user);
}
this.displayUser = function (user) {
this.user = user;
}
});
This is the controller where I want to use the service:
app.controller('DisplayUserController', ['$scope','UserService',
function($scope, UserService) {
$scope.user = UserService.user;
}]);
This is the HTML where I am passing the user object to user directive:
<div ng-controller="DisplayUserController">
<div>{{user.firstName}}</div>
<div>{{user.middleName}}</div>
<div>{{user.lastName}}</div>
</div>
Why am I getting "Unknown provider: userProvider <- user" error? Please help.
You need to bind the ngModel to your directive:
.directive('user', function() {
return {
restrict: 'E',
scope:{
'user': '=ngModel'
},
templateUrl:'display-single-user.html',
controller: function($scope) {
var user = $scope.user;
$scope.firstName = user.firstName;
$scope.middleName = user.middleName;
$scope.lastName = user.lastName;
$scope.email = user.email;
$scope.dob = user.dob;
}
};
});
There was a problem in my directive, I was using internal controller that also needed the UserService therefore added it as a dependency and it started working. Now, please let me know if this is a correct practice to follow.
angular.module('myApp').directive('user', ['UserService', function() {
return {
restrict: 'E',
templateUrl:'templates/display-single-user.html',
controller: function($scope, UserService) {
$scope.firstName = UserService.user.firstName;
$scope.middleName = UserService.user.middleName;
$scope.lastName = UserService.user.lastName;
$scope.email = UserService.user.email;
$scope.dob = UserService.user.dob;
}
};
}]);
Related
I have two controllers. I want to update a variable from one controller to another controller using service but its not updating.
I want the variable $scope.names in controller 'select' to update in the controller 'current' and display it
app.controller('select', ['$scope', '$http', 'myService', function($scope,$http, myService) {
$http.get('/myapp/stocknames').
success(function(data) {
$scope.names=data;
myService.names=data;
});
}]);
I am using myService to exchange the data between the two controllers. I have declared in my service.
app.service('myService', function($http, $rootScope) {
this.names=[]
});
app.controller('current', ['$scope', '$http', 'myService', function($scope,$http, myService) {
$scope.names=myService.names;
console.log($scope.names);
}]);
Can you please help. How should I make the current controller update the data once the $scope.names variable in the select controller is updated?
According to me what I am doing should work :-/
There are many way to archive this:
First:
By watching for the service variable data change
var app = angular.module('plunker', []);
app.service('dataService', function() {
this.serviceData = "test";
});
app.controller('MainCtrl', function($scope, dataService) {
$scope.mainClickHandler = function(mainData) {
dataService.serviceData = mainData;
}
});
app.controller('SubCtrl', function($scope, dataService) {
$scope.name = 'World';
$scope.getServiceData = function() {
return dataService.serviceData;
}
$scope.$watch("getServiceData()", function(newValue, oldValue) {
if (oldValue != newValue) {
$scope.name = newValue;
}
});
});
http://plnkr.co/edit/G1C81qvDD179NILMMxWb
Second:
Using event broadcast
var app = angular.module('plunker', []);
app.factory('dataService', function($rootScope) {
var serviceData = {
"mydata": "test"
};
$rootScope.$watch(function() {
return serviceData.mydata;
}, function(newValue, oldValue, scope) {
$rootScope.$broadcast('dataService:keyChanged', newValue);
}, true);
return serviceData;
});
app.controller('MainCtrl', function($scope, dataService) {
$scope.mainClickHandler = function(mainData) {
dataService.mydata = mainData;
}
});
app.controller('SubCtrl', function($scope, $rootScope, dataService) {
$scope.name = 'World';
$rootScope.$on('dataService:keyChanged', function currentCityChanged(event, value) {
console.log('data changed', event, value);
$scope.name = value;
});
});
http://plnkr.co/edit/tLsejetcySSyWMukr89u?p=preview
Third:
Using callback
var app = angular.module('plunker', []);
app.service('dataService', function() {
var serviceData = "test";
var callback = null;
this.updateServiceData = function(newData){
serviceData = newData;
if(null!==callback)
{
callback();
}
};
this.getServiceData = function(){
return serviceData;
};
this.regCallback = function(dataCallback){
callback = dataCallback;
};
});
app.controller('MainCtrl', function($scope, dataService) {
$scope.mainClickHandler = function(mainData) {
dataService.updateServiceData(mainData);
}
});
app.controller('SubCtrl', function($scope, dataService) {
$scope.name = 'World';
$scope.dataChangeCalback = function() {
$scope.name = dataService.getServiceData();
}
dataService.regCallback($scope.dataChangeCalback);
});
http://plnkr.co/edit/vrJM1hqD8KwDCf4NkzJX?p=preview
One way to do this is we can bind the entire service to the scope:
myApp.controller('select', ['$scope', '$http', 'myService', function($scope,$http, myService) {
$scope.myService = myService;
$scope.click = function () {
myService.names = "john";
};
And then we change the myService.names directly
current controller should look like this:
myApp.controller('current', ['$scope', '$http', 'myService', function($scope,$http, myService) {
$scope.names=myService.names;
console.log($scope.names);
$scope.$watch(function() { return myService.names; }, function(newVal, oldVal) {
$scope.names = newVal;
});
}]);
}]);
We then use a watcher expression.
or a watcherExpression See for more details.
I've searched and can't quite find someone with the same circumstances, I'm using angular routing to perform CRUD on a mock db.json server and when I execute the 'update' function, it changes the value in the database, but always redirects me to a blank page that just says 'Cannot POST /'. Even though the request actually went through. I'd just like it to return to the /clients page once the request is finished. I'm using browserify to include angular and angular-route. Thanks in advance :)
// Router
var UNRealtyApp = angular.module('UNRealtyApp', ['ngRoute'])
UNRealtyApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/clients', {templateUrl: 'app/views/clients.html', controller: 'clientListCtrl'})
.when('/add-client', {templateUrl: 'app/views/client-add.html', controller: 'clientAddCtrl'})
.when('/edit-client/:id', {templateUrl: 'app/views/client-edit.html', controller: 'clientEditCtrl'})
.otherwise({redirectTo: '/404'});
}]);
//Client CRUD
UNRealtyApp.controller('clientListCtrl', function ($scope, $http){
console.log('clientListCtrl activated')
$http.get('http://localhost:3000/clients/').success(function(data) {
$scope.clients = data;
})
})
UNRealtyApp.controller('clientAddCtrl', function ($scope, $http, $location){
console.log('clientAddCtrl activated')
$scope.master = {};
$scope.activePath = null;
$scope.add_new = function(client, AddNewForm) {
console.log('add_new activated')
$http.post('http://localhost:3000/clients/', client).success(function(){
$scope.reset();
$scope.activePath = $location.path('/clients');
});
$scope.reset = function() {
console.log('reset activated')
$scope.client = angular.copy($scope.master);
};
$scope.reset();
}
})
UNRealtyApp.controller('clientEditCtrl', function ($scope, $http, $location, $routeParams){
console.log('clientEditCtrl activated')
var id = $routeParams.id;
// $scope.activePath = null;
$http.get('http://localhost:3000/clients/' + id).success(function(data) {
$scope.clients = [data];
});
$scope.update = function(client){
console.log('update activated')
$http.put('http://localhost:3000/clients/' + id, client).success(function(data) {
$scope.clients = data;
$scope.activePath = $location.path('clients');
});
};
$scope.delete = function(client) {
console.log('delete activated')
var deleteClient = confirm('Are you sure you want to delete?');
if (deleteClient) {
$http.delete('http://localhost:3000/clients/' + client.id);
$scope.activePath = $location.path('clients');
}
}
})
I have a basic app currently that has a list of names in a sidebar nav populated from a json call to my server. When the user clicks on a name in the sidebar, it updates the nameService to the name clicked on by the user.
When the nameService gets updated, I wanted to name-data view to make another json call the the server for the correct json file based on the name that the user clicked on.
I am having difficulty updating a view based on changes in a value contained in my service. I have two controllers and a service currently in my AngularJS app as follows:
app.js
var app = angular.module("myapp", ['ui.bootstrap']);
app.directive("sideBar", ['$http', 'nameService', function($http, nameService) {
return {
restrict: 'E',
templateUrl: "views/sidebar.html",
controller: function($scope) {
$scope.updateName = function(name) {
nameService.setName(name);
};
$http.get('../data/names.json').
success(function(data, status, headers, config) {
$scope.names = data;
});
}
};
}]);
app.directive("nameData", ['$http', 'nameService', function($http, nameService) {
return {
restrict: 'E',
templateUrl: "views/name-data.html",
controller: function($scope) {
$scope.service = nameService;
var path = "../data/" + $scope.service.name + ".json";
$http.get(path).success(function(response) {
$scope.info= response.info;
});
}
};
}]);
app.service('nameService', ['$http', function($http) {
this.name = "TestName";
this.setName = function(name) {
this.name = name;
};
this.getName = function() {
return this.name;
};
}]);
How can I update the nameData view whenever the user clicks on the sidebar nav and updates the nameService.name property?
I tried putting $scope.service.name under a watch but that didn't seem to do anything.
Is there some form of angular magic I can use to dynamically make new json calls when a new user is selected from the name list contained in my side bar?
maybe angular event broadcasts?
add rootScope to service and broadcast an event on name change:
app.service('nameService', ['$http','$rootScope', function($http,$rootScope) {
this.name = "TestName";
this.setName = function(name) {
this.name = name;
$rootScope.$broadcast('nameService-nameChanged');
};
this.getName = function() {
return this.name;
};
}]);
and then bind to that event on your directive controller scope:
app.directive("nameData", ['$http', 'nameService', function($http, nameService) {
return {
restrict: 'E',
templateUrl: "views/name-data.html",
controller: function($scope) {
$scope.service = nameService;
//turned your load mechanism in to a function
$scope.loadNameData = function(){
var path = "../data/" + $scope.service.name + ".json";
$http.get(path).success(function(response) {
$scope.info= response.info;
});
}
//initial load
$scope.loadNameData();
//subscribe to broadcast event, this will call $scope.loadNameData when the 'nameService-nameChanged' event is broadcast
$scope.$on('nameService-nameChanged',$scope.loadNameData);
}
};
}]);
I am creating a form with several input options for the end user, but with one input which I would like to be an UUID/GUID.
Here's what I have so far for the module (project.js):
angular.module('project', ['ngRoute', 'firebase'])
.value('fbURL', 'https://private.firebaseio.com/')
.factory('Projects', function($firebase, fbURL) {
return $firebase(new Firebase(fbURL));
})
.config(function($routeProvider) {
$routeProvider
.when('/', {
controller:'ListCtrl',
templateUrl:'list.html'
})
.when('/edit/:projectId', {
controller:'EditCtrl',
templateUrl:'detail.php'
})
.when('/new', {
controller:'CreateCtrl',
templateUrl:'detail.php'
})
.otherwise({
redirectTo:'/'
});
})
.controller('ListCtrl', function($scope, Projects) {
$scope.projects = Projects;
$scope.project = { trackid: 'UUID' };
})
.controller('CreateCtrl', function($scope, $location, $timeout, Projects) {
$scope.project = { trackid: 'UUID' };
$scope.save = function() {
Projects.$add($scope.project, function() {
$timeout(function() { $location.path('/'); });
});
};
})
.controller('EditCtrl',
function($scope, $location, $routeParams, $firebase, fbURL) {
var projectUrl = fbURL + $routeParams.projectId;
$scope.project = $firebase(new Firebase(projectUrl));
$scope.destroy = function() {
$scope.project.$remove();
$location.path('/');
};
$scope.save = function() {
$scope.project.$save();
$location.path('/');
};
$scope.project = { trackid: 'UUID' };
});
And here's what I have for the form input (in my detail.php file):
<form name="myForm">
<label>Track ID</label>
<input type="text" name="trackid" ng-model="project.trackid" disabled>
As you can tell, in this example I'm simply inserting the text "UUID" where I would actually like to insert an UUID. I can't however seem to figure out how to insert a function there that would be generating this UUID. Any help would be very much appreciated! Thank you!
If you have a function that returns the value needed you can simply do:
function getUUID(){
var result = /* parse value */
return result;
}
$scope.project ={ trackid: getUUID() };
DEMO
i am using one of the basic concept of angularjs that child controller inherit from parent controller. so i have writen the following code :
var editChannelCtrl = function ($scope, $route, $location, youtube) {
$scope.loading = false;
$scope.saved = false;
$scope.errors = [];
if (angular.isDefined($route.current.params.id)) {
$scope.isOldChannel = true;
$scope.isNewChannel = false;
} else {
$scope.isNewChannel = true;
$scope.isOldChannel = false;
}
};
editChannelCtrl.$inject = ['$scope', '$route', '$location', 'youtube'];
editChannelCtrl.resolve = {
channel: ['ServiceChannel' , function (ServiceChannel) {
return ServiceChannel.ChannelLoader();
}]
};
var oldChannelCtrl = function ($scope, $location, channel) {
$scope.channel = channel;
};
oldChannelCtrl.$inject = ['$scope' , '$location', 'channel'];
var newChannelCtrl = function ($scope, $location, Channel) {
$scope.channel = {
id: null,
version: 1
};
};
newChannelCtrl.$inject = ['$scope' , '$location', 'Channel'];
and for routes what i do , that i resolve the channel that load the channel for the edit form with the following code.
.when('/admin/refactor/channel/edit/:id', {
controller: editChannelCtrl,
templateUrl: '/admin/assets/views/channelForm.html',
resolve: editChannelCtrl.resolve
})
.when('/admin/refactor/channel/new', {
controller: editChannelCtrl,
templateUrl: '/admin/assets/views/channelForm.html'
})
but i don't know why angularjs don't figure how to inject channel to oldChannelCtrl ?