AngularJS not working when I pass controller to the view
I have a problem and I can't troubleshoot it. In my simple app (very simple) I have a service that provides of users info. In angular I have an mvc which is trying to bind the info into the view.
The problem: when I pass the controller to the view, in the route directive, angular stops working in the view. I'm using a simple test {{1+1}} to verify if angular is working.
controller:
App.controller("loginController", function ($scope, usersModel) {
$scope.users = usersModel.getUsers();
})
model
App.service("usersModel", function () {
this.getUsers = function ($scope) {
$http.get("http://localhost:50765/api/users");
}});
The service should inject the $http service and return the promise that it returns
App.service("usersModel", function ($http) {
this.getUsers = function () {
return $http.get("http://localhost:50765/api/users");
}
});
And extract the data from the promise:
App.controller("loginController", function ($scope, usersModel) {
var promise = usersModel.getUsers();
promise.then(function(response) {
$scope.users = response.data;
});
})
Related
this is my angular controller which i use it in laravel but when i submit my form i get
MethodNotAllowedHttpException
app.service('post_service', function ($http) {
create = $http.POST('/post', JSON.stringify(data)).then(
function mySuccess(response) {
debugger
$scope.myWelcome = response.data;
},
function myError(response) {
debugger
$scope.myWelcome = response.statusText;
}
)
});
app.controller('postController', ['$scope', function ($scope, post_service) {
$scope.message = 'AddPosts';
// $scope.post=null;
$scope.save = function (data) {
post_service.create(data)
}
}]);
my route config is this :
Route::resource('post', 'PostController');
like you see i using resource controller which allow us to use all type of routing like store index or....
for more detail: my form is simple angular form which contains no token string like csrfToken or some thing like that
You can use the this Route::post('/postData', 'PostController#action');
in the angular service
$http.POST('/postData', JSON.stringify(data)).then(
code here
);
I want to send object to angularjs Controller using MVC Controller Action is it possible?
suppose
public ActionResult Dashboard()
{
return View();
}
I want to pass object to app.js how to do this
Your question is a bit vague , you need to be more specific on what exactly you are trying to do.
Generally , this his how you would get data in Angular from the MVC application.
In Case of MVC/WebAPI , you should use actions to return JSON result back to the angular service which can then be processed by angular.
Example below :
app.factory('myService', function($http) {
var myService = {
GetData: function() {
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http.get('<ActionURL>').then(function (response) {
// The then function here is an opportunity to modify the response
console.log(response);
// The return value gets picked up by the then in the controller.
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return myService;
});
app.controller('MainCtrl', function( myService,$scope) {
// Call the async method and then do stuff with what is returned inside our own then function
myService.GetData().then(function(d) {
$scope.data = d;
});
});
After this services is called from the MainCtrl , angular will have the data from the MVC action available in its $scope.data variable.
I tried to write factory method in Angular JS:
.factory('FriendsFactory', function(){
var friend = {};
friend.delete = function(id) {
notificationsModal.show('danger', messages_info[86]);
notificationsModal.confirm(function() {
this.deleteAjax(event, id, type);
})
}
friend.deleteAjax = function (event, id, type){
var target = angular.element(event.target);
var request = $http({
method: "POST",
url: "/subscribe/deletesubscriber",
data: $.param({ id : id, type : type }),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
request.success(function () {
target.closest('.notif-item').remove();
$scope.counter--;
});
request.error(function () {
// TODO
});
}
return friend;
})
This code has two methods: friend.delete() also friend.deleteAjax()
Calling functions from Factory:
.controller('FriendsController', ['$scope','$http', 'friendsFactory', function($scope, $http) {
$scope.deleteUser = function (idUser) {
friendsFactory.delete(idUser);
}
}])
I need decrement variable $scope.counter in friend.deleteAjax() ajax response, regardless controller from was called factory.
I can do duplicate in each controller:
$scope.counter = 10; and after call factory, but it is not good
Although the answer suggested by #JBNizet is absolutely correct but if you are bound to use the code in the way it is, then you can do two things. First is to simply pass the $scope from controller to service call (which is not a cleaner approach is not recommended):
$scope.deleteUser = function (idUser) {
friendsFactory.delete(idUser, $scope);
}
And you can use the scope inside the factory.
The second option to use current controller's scope to root scope and then use this in the factory.
In your controller
$scope.deleteUser = function (idUser) {
$rootScope.callingControllerScope = $scope;
friendsFactory.delete(idUser);
}
In your factory
friend.deleteAjax = function (event, id, type){
console.log($rootScope.callingControllerScope.counter);
// your code
}
And you also need to fix your dependency injection:
.controller('FriendsController', ['$scope','$http', 'FriendsFactory', function($scope, $http, friendsFactory) {
$scope.deleteUser = function (idUser) {
friendsFactory.delete(idUser, $scope);
}
}]);
You're doing many, many things wrong:
Using friendsFactoryinstead of FriendsFactory:
.controller('FriendsController', ['$scope','$http', 'friendsFactory'
here --------^
Forgetting to declare friendsFactory as an argument of the controller function:
.controller('FriendsController', ['$scope','$http', 'friendsFactory', function($scope, $http) {
here ----^
Accessing an undefined $scope variable in the service:
$scope.counter--;
^--- here
Doing DOM manipulation in a service...
The service responsibility is not to manipulate the DOM and the controller scope.
The DOM should be modified using directives in the html template.
The controller scope should be managed by the controller, not by the service. Return the promise request from the deleteAjax() function, and let the controller register a success callback, rather than doing it in the service. This callback will then be able to access the controller scope.
Note that most errors are basic JavaScript error that should be signalled by a good JavaScript editor, or at least by looking at errors in the console of your browser.
I'm not able to get the data binding between controller and service working.
I have a controller and a factory which makes an HTTP call. I would like to be able to call the factory method from other services and see the controller attributes get updated. I tried different options but none of them seem to be working. Any ideas would be greatly appreciated.
Please see the code here:
http://plnkr.co/edit/d3c16z?p=preview
Here is the javascript code.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});
app.controller('EventDetailCtrl', ['$http', 'EventDetailSvc', '$scope',
function ($http, EventDetailSvc, $scope) {
this.event = EventDetailSvc.event;
EventDetailSvc.getEvent();
console.log(self.event);
$scope.$watch(angular.bind(this, function () {
console.log('under watch');
console.log(this.event);
return this.event;
}), function (newVal, oldVal) {
console.log('under watch2');
console.log(newVal);
this.event = newVal;
});
}])
.factory('EventDetailSvc', ['$http', function ($http) {
var event = {};
var factory = {};
factory.getEvent = function() {
$http.get('http://ip.jsontest.com')
.then(function (response) {
this.event = response.data;
console.log('http successful');
console.log(this.event);
return this.event;
}, function (errResponse) {
console.error("error while retrieving event");
})
};
factory.event = event;
return factory;
}]);
It seems to me that you have nested the event object inside of a factory object. You should be returning event directly instead wrapping it with factory. As it stands now you would need to call EventDetailSvc.factory.event to access your object.
I have a basic data Service which will be used across Controllers. But I'm having an issue grabbing some data that's been added via $http.
Service:
angular.module('core').service('FormService', ['$http', function($http) {
var _this = this;
_this.dropdownData = {
contactTimes: ['Anytime','Morning','Afternoon','Evening'],
industries: {},
};
$http.get('/json').success(function(resp){
_this.dropdownData.industries = resp.industries;
});
}]);
Controller:
angular.module('core').controller('SignupController', ['$scope', '$http', '$state', 'FormService', function($scope, $http, $state, FormService) {
console.log(FormService.dropdownData); // Shows full object incl industries
console.log(FormService.dropdownData.industries); // empty object {}
}]);
How do I get FormService.dropdownData.industries in my controller?
Create a service like below
appService.factory('Service', function ($http) {
return {
getIndustries: function () {
return $http.get('/json').then(function (response) {
return response.data;
});
}
}
});
Call in controller
appCtrl.controller('personalMsgCtrl', ['$scope', 'Service', function ($scope, Service) {
$scope.Industries = Service.getIndustries();
}]);
Hope this will help
Add a method to your service and use $Http.get inside that like below
_this.getindustries = function (callback) {
return $http.get('/json').success(function(resp){
_this.dropdownData.industries = resp.industries;
callback(_this.dropdownData)
});
};
In your controller need to access it like below.
angular.module('core').controller('myController', ['$scope', 'FormService', function ($scope, FormService) {
FormService.getDropdownData(function (dropdownData) {
console.log(dropdownData); // Shows full object incl industries
console.log(dropdownData.industries); // object {}
});
} ]);
Given that your console log shows the correct object, that shows your service is functioning properly. Only one small mistake you have made here. You need to access the data attributes in your return promise.
angular.module('core').service('FormService', ['$http', function($http) {
var _this = this;
_this.dropdownData = {
contactTimes: ['Anytime','Morning','Afternoon','Evening'],
industries: {},
};
$http.get('/json').success(function(resp){
//note that this is resp.data.industries, NOT resp.industries
_this.dropdownData.industries = resp.data.industries;
});
}]);
Assuming that you're data is indeed existing and there are no problems with the server, there are quite a few possible solutions
Returning a promise
angular.module('core').service('FormService', ['$http', function($http) {
var _this = this;
_this.dropdownData = {
contactTimes: ['Anytime','Morning','Afternoon','Evening'],
industries: {},
};
_this.dropdownData.industries = $http.get('/json');
}]);
//Controller
FormService.industries
.then(function(res){
$scope.industries = res.industries
});
Resolving with routeProvider / ui-route
See: $http request before AngularJS app initialises?
You could also write a function to initialize the service when the application starts running. At the end of the day, it is about waiting for the data to be loaded by using a promise. If you never heard about promises before, inform yourself first.
The industries object will be populated at a later point in time when the $http call returns. In the meantime you can still bind to the reference in your view because you've preserved the reference using angular.copy. When the $http call returns, the view will automatically be updated.
It is also a good idea to allow users of your service to handle the event when the $http call returns. You can do this by saving the $promise object as a property of industries:
angular.module('core').service('FormService', ['$http', function($http) {
var _this = this;
_this.dropdownData = {
contactTimes: ['Anytime','Morning','Afternoon','Evening'],
industries: {},
};
_this.dropdownData.industries.$promise = $http.get('/json').then(function(resp){
// when the ansyc call returns, populate the object,
// but preserve the reference
angular.copy( resp.data.industries, _this.dropdownData.industries);
return _this.dropdownData.industries;
});
}]);
Controller
app.controller('ctrl', function($scope, FormService){
// you can bind this to the view, even though the $http call has not returned yet
// the view will update automatically since the reference was preserved
$scope.dropdownData = FormService.dropdownData;
// alternatively, you can hook into the $http call back through the $promise
FormService.dropdownData.industries.$promise.success(function(industries) {
console.log(industries);
});
});