Here is the code..
Service:
self.getNewCourses = function() {
return "temp variable";
}
Controller:
$mmCourses.getNewCourses().then(function(data) {
$scope.names = data;
alert($scope.names);
});
getNewCourses function in your service is just returning a string and NOT a promise. Instead of doing .then on it , use it like below :
$scope.names = $mmCourses.getNewCourses();
console.log($scope.names);
Make sure you are returning the object self from the service and $mmCourses is injected in the Controller.
First create a service, then inject in controller then use function using yourService.yourFunctionName()....
See icoxfog417's fiddle
Hope this will help you.
Related
I'm facing a problem with angular JS Controller function. I have a controller and in that controller I have bunch of functions which are getting called from a service which contains HTTP get and post requests.
To be specific my question is inside a controller, when I try to write:
$scope.functionName = function()
{
//some code
}
My function doesn't get called at all. And when I do the following my function gets called but the scope goes undefined for rest of the functions.
app.controller("ControllerName", function ($scope, ServiceName) {
getAll();
getAppKey();
getAppDefaults();
function getAll(){//some code}
function getAppKey(){//some code}
function AppDefaults(){//some code
})
I'm not sure where I'm going wrong. I would really appreciate anyone's help who can help me out with this issue.
I think you are defining function with $scope and calling function without $scope.
This code will work:
app.controller("ControllerName", function ($scope, ServiceName) {
$scope.getAll = function{
console.log("function called");
}
$scope.getAll();
})
And this code will not work as expected:
app.controller("ControllerName", function ($scope, ServiceName) {
$scope.getAll = function{
console.log("function called");
}
getAll();
})
'...bunch of functions which are getting called from a service...' ?
You can't call function from controller in service. What you can do is to use functions from service in controller.
If you want to use methods from service inside your controller, first inject service(you already did that),
then call it:
ServiceName.getAll();
ServiceName.getAppKey();
...
etc.
If you want to use this functions from controller, make another service/factory put this functions inside that service, inject service2 in service and again you can use them like:
ServiceName2.getAll();
ServiceName2.getAppKey();
I am not sure what are you trying to acomplish, maybie this?
this code works:
app.controller('MainCtrl', function($scope) {
$scope.submit = function() {
alert("called.........");
}
defaultFunction = function() {
alert("defaultFunction called.........");
}
defaultFunction();
});
$scope is added when you want to use in view, if you need to use it in controller, no need for $scope
you can change http://jsfiddle.net/B9RsQ/45/ to test it
Admittedly I am relatively new to Angular but I've come unstuck using ngResource for a REST call.
I followed a factory pattern which seems to be relatively common.
However my I only get access to the REST response by using a $promise.then. Which I understand you do not require with $resource.
So I have this factory...
var LookupsService = angular.module('LookupsService', ['ngResource']);
LookupsService.factory('Lookups', ['$resource',
function ($resource) {
return $resource('http://localhost:5001/api/lookups', {});
}]);
And this fails (as undefined)
alert(Lookups.get().foo);
But this is fine
Lookups.get()
.$promise
.then(function (lookups) {
alert(lookups.foo);
});
I'm obviously missing something here. Some kind of schoolboy error ;-)
UPDATE
Thanks for all your help - it is now very clear. I gave #fikkatra the tick for the clarity of her answer and snippet. But pretty much all the answers were helpful. I must be careful using Alert for debugging!
Using alert on a promise won't work, i.e. it won't show the results within the promise. However, angular has been designed to use the $resource service directly to bind to the scope. This means you can bind a $resource result to a scope object, and angular will take into account that the scope object is a promise when applying the binding. That's why alert(resourceResult) won't work, but $scope.myObj = resourceResult; (and then bind it in a view), will work.
Inserted code snippet to explain things more clearly:
var app = angular.module('myapp', ['ngResource']);
app.controller('myctrl', function($scope, $resource) {
//this won't work:
//alert("won't work: " + $resource('https://api.github.com/users/fikkatra').get());
//but this will work
$resource('https://api.github.com/users/fikkatra').get().$promise.then(function(user) {
alert("will work: " + user.login);
});
//directly assigning $resource result to scope will work:
$scope.user = $resource('https://api.github.com/users/fikkatra').get();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-resource.js"></script>
<div ng-app="myapp" ng-controller="myctrl">
{{user.login}}
</div>
You don't have to, and shouldn't need to, use $promise with $resource. The $resource service can be used like this:
(function() {
'use strict';
angular
.module('app')
.factory('MyService', MyService);
MyService.$inject = ['$resource'];
function MyService($resource) {
return $resource('my/url/:id', {id: "#id"}, {
'query': { isArray: false },
'update': { method: "put" }
});
}
})();
It gives you back several HTTP methods that you can use in your code without you having to write them yourself. To use them you can do something like this:
function getActionTypes(){
MyService.query(
function success(result){
// do stuff with result
},
function failure(result){
console.error(result);
});
}
You actually don't have to use the $promise, it's just available if you want to.
Codepen: http://codepen.io/troylelandshields/pen/bpLoxE
angular.module('app', ['ngResource'])
.service('exampleSvc', function($resource){
return $resource('http://jsonplaceholder.typicode.com/posts/1', {});
})
.controller('exampleCtrl', function(exampleSvc, $scope){
$scope.result = exampleSvc.get();
exampleSvc.get().$promise.then(function(val){
//Do some other logic here on the val
$scope.promiseResult = val;
});
});
You can also assign the result of .get() to a variable on the scope and the result will be filled in when the request is resolved (in the first example above). This works well for assigning data to an object on your scope that will just end up being displayed on the page, but might not work well for other situations where you need to use the result of the .get() to do something else.
According to the specification you can pass in a success callback as outlined in this little code snippet.
var User = $resource('/user/:userId', {userId:'#id'});
var user = User.get({userId:123}, function() {
user.abc = true;
user.$save();
});
The success function callback will be called when the resource finishes.
Alternatively, you can use the promise syntax with get(), except you don't need to add your own promise as per your example. Instead you can simply do the following:
Lookups.get()
.then(function (lookups) {
alert(lookups.foo);
});
This is because get() returns a promise. When the promise is evaluated successfully then() will be called
I am new to angular js.
I need to access data from my controller to service.
I tried using $rooyScope but my service needs to be loaded first and then my controller so using $rooyScope gives me error.
so i am unable to get the data stored in $rooyScope on service.
Can any suggest me a options that suits my expectation
Thank you for your help
Use functions in the service to set a service variable
angular.module('myServiceModule', []).
factory('testService', function() {
var myVariable;
return setVariable: function(parameter) {
myVariable = parameter;
// DO SOMETHING ELSE IF YOU WANT
},
return getVariable: function() {
return myVariable;
}
});
then in your controller inject the service and call the service function
angular.module('myControllerModule', []).
controller('testController, ['testService', function(testService) {
testService.setVariable('TEST');
console.log(testService.getVariable());
}]);
I'm doing the CA course for angular. Here is the code for the controller, in controller.js:
app.controller('MainController', ['$scope', 'forecast', function($scope, forecast) {
forecast.success(function(data) {
$scope.fiveDay = data;
});
}]);
Here is the code for the service, in service.js:
app.factory('forecast', ['$http', function($http) {
return $http.get('http://s3.amazonaws.com/codecademy-content/courses/ltp4/forecast-api/forecast.json')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
So I guess factories are services? What exactly is a service? I saw this explanation but it isn't the most clear to me.
Services
Syntax: module.service( 'serviceName', function ); Result: When
declaring serviceName as an injectable argument you will be provided
with an instance of the function. In other words new
FunctionYouPassedToService().
In the two code snippets, when is the service called? What is the forecast.service doing in the controller? What is forecast = in the controller? Is it an object?
An Angular factory is a function which when called will return the service. The service can be pretty much anything. In your case, you are returning the result of $http(...).success(..).error(...) in your return statement which is a promise.
So when you instantiate the controller, the factory gets called, calls inside the function body the HTTP call and returns a promise.
In the controller you receive a promise object which you can call success or error on.
This way, you cannot repeat the HTTP call, since once factories are called, all other controller receive the same instance (in this case the HTTP call is made only when the first controller is instantiated with the forecast dependency, all other controllers with that dependency get the same promise for the already called HTTP request)
try this
$http.get('//s3.amazonaws.com/codecademy-content/courses/ltp4/forecast-api/forecast.json') instead of $http.get('http://s3.amazonaws.com/codecademy-content/courses/ltp4/forecast-api/forecast.json')
helped to me.
Two Important Notes:
1. My goal is to AVOID using $scope in this case since it's my understanding that impedes the new "controller as" syntax.
2. My problem is likely a variable scope issue and so perhaps just clarifying the proper JS way might solve the problem.
Nevermind the exports, I'm working with browserify in my workflow.
I have this working code:
exports.IntroCtrl = function($scope, $http) {
$scope.introData = [];
$http.get('data/intro.json')
.success(function(res){
$scope.introData = res;
});
};
That ideally I'd like to work as something like this, for the sake of using the "controller as" syntax.
exports.IntroCtrl = function($http) {
this.introData = [];
$http.get('data/intro.json')
.success(function(res){
introData = res;
});
};
The problem is that the $http service seems to be executing before my initial this.introData declaration since I get a variable not defined error.
If tell this.introData = $http.get… then it returns an array of 5 objects that I can't access and intro.json only contains 4.
Thanks for any guidance/help.
First of all create a service for the http call. It is very convenient way to get the callback in the controller and then assign your controller as variables. Here is the factory for you:
Factory
app.factory('getDataService',function ($http) {
return {
getData:function(callback){
$http.get('data/intro.json')
.success(callback)
});
}
}
});
In your controller you get inject the getDataService and bind the data like this:
Controller:
app.controller('testController',['getDataService',function(testDataService){
this.introData = [];
testDataService.getData(function(data){
this.introData = data;
});
}]);
Here you need to bind the introData of the controller function.
You have to remember this variable that reference the controller instance, and use it later in the success callback like this:
exports.IntroCtrl = function($http) {
this.introData = [];
var ctrl = this; // remember 'this', the controller instance, to use in the success callback below
$http.get('data/intro.json')
.success(function (res) {
ctrl.introData = res;
});
};
Hope this helps.