Need help on Angular Factory - javascript

Hi SO angular community !
I'm very confused, I think I have understand the factory purpose and concept, but seems not ...
Here is my problem (surely simple for you) :
I want to use my REST API (working perfectly) using Angular and .factory ...
rest.js
var app = angular.module('urlShortener', ['ngRoute', 'ngResource']);
app.factory('API', ['$resource',
function($resource){
return $resource('/link'});
}],{
get: {method:GET},
post: {method:POST},
put: {method:PUT},
delete: {method:DELETE},
}
);
app.controller('GetAll', function ($scope) {
$scope.links = API.get();
});
index.ejs
<div ng-controller="GetAll">
<ul>
<li ng-repeat="link in links">
<p>{{link.itemId}} --> {{link.url}}</p>
</li>
</ul>
</div>
Not working ... 2 hours I'm consulting the Angular API, and no solutions :/
Please help me I'm wasting time :'(
\\\\ SOLUTION ////
rest.js
app.factory('API', ['$resource', function($resource) { return $resource('/link'); }]);
app.controller('GetAll', ['$scope', 'API', function ($scope, API) {
API.query().$promise.then(function(links) {
$scope.links = links;
});
}]);
Thanks to #dfsq help :)

You can't just assign $resource instance to $scope.links, you need to do it when underlying promise resolves:
app.controller('GetAll', ['$scope', 'API', function ($scope, API) {
API.get().$promise.then(function(links) {
$scope.links = links;
});
}]);

You have to inject "API" in your controller.
app.controller('GetAll', function ($scope, API) {
$scope.links = API.get();
});

If your rest service returns an array of objects you need to use query function.
$scope.links = API.query(); // instead of API.get()
If you need to do anything else when the promise returns use something like this:
API.query().$promise.then(function(result){
$scope.links = result;
// any other operation related to the request here
});

if you want to do api requests, use $http
this is a piece of code I use in my app:
angular
.module('myApp')
.factory('apiFactory', apiFactory);
function apiFactory($http) {
return {
getDataFromApi: getDataFromApi,
};
function getDataFromApi(url) {
return $http({
method: 'GET', // or post or whatever
url: url,
headers: {
...
}
})
.then(success)
.catch(fail);
function success(response) {
return response.data;
}
function fail(response) {
// handle error
}
}
}

Is this what you are looking for?
API For Resources
services.factory('Api', ['$resource',
function($resource) {
return {
Recipe: $resource('/recipes/:id', {id: '#id'}),
Users: $resource('/users/:id', {id: '#id'}),
Group: $resource('/groups/:id', {id: '#id'})
};
}]);
function myCtrl($scope, Api){
$scope.recipe = Api.Recipe.get({id: 1});
$scope.users = Api.Users.query();
...
}

Related

AngularJS eager loading json file

I am new to angularJS. Sorry, If I am not clear with the question.
Here's the issue.
I have a JSON file ranging 20KB in size. When I try to load this file using 'factory' method, I am getting null value.
var app = angular.module('moonApp', []);
app.factory('MainSource', ['$http', function($http){
var data={source:null};
$http.get('/datafile.json',function(output){
data.source=output;
console.log(data.source); // it works
});
return data;
}]);
app.controller('appCtrl',['$scope','MainSource',function($scope,MainSource){
console.log(MainSource.source); // Not works - getting Null value
}]);
For the above code I am getting NULL value in the console. But If i try it inside the $http success method, it renders the json file contents.
Please help me. Thanks in advance.
I am using $resource to read json file. The following code can load a json file for you.
var app = angular.module('moonApp', ['ngResource']);
app.module('moonApp')
.service('MainSource', function($resource) {
return $resource('/datafile.json', {}, {
query: {
method: 'GET',
isArray: true
}
});
})
Now, inject and use the service in controller
app.controller('appCtrl',['$scope','MainSource',function($scope,MainSource){
MainSource.query(function (data) {
$scope.source = data;
console.log($scope.source); // hopefully you'll see the JSON data here
});
}]);
You can define a function on your MainSource factory and return a promise which you are able to resolve in your controller with the then() call. Please give this a try.
app.factory('MainSource', ['$http', function ($http) {
function getSource() {
return $http.get('/datafile.json', function () {
});
}
return {
'getSource': getSource
}
}]);
app.controller('appCtrl', ['$scope', 'MainSource', function ($scope, MainSource) {
MainSource.getSource().then(function (response) {
console.log(response);
});
}]);
Try like this:
console.log(MainSource.data.source);

How to make an AngularJS service that will retrieve data from Behance API?

I have been trying to create a AngularJS service that will get data from behance profiles.
I am injecting the $http and $q services to enable me to make requests to Behance API.
I am using a literal string for the url parameter for now to see how to resolve my issue. I will refactor my code to make it dynamic later.
behance.js File with the service relative to my Angular app.
'use strict';
angular
.module('angularPortfolioApp')
.factory('behanceUserData', ['$q', '$http',
function($q, $http) {
var service = {
getUser: function(username) { //ignore the parameter in this function I plan on implementing that after I have my question resolved.
var d = $q.defer();
$http({
method: 'JSONP',
url: 'https://www.behance.net/v2/users/USERNAME?api_key=XXX'
}).success(function(data) {
d.resolve(data);
}).error(function(reason) {
d.reject(reason);
});
return d.promise;
}
};
return service;
}
]);
app.js Declaring my Angular app with it's required dependencies.
'use strict';
angular.module('angularPortfolioApp', ['ngResource']);
In Chrome dev tools console I get an error of Uncaught SyntaxError: Unexpected token :
After doing some research I did find an article that stated that Angular does tack on a ":1" to the end of a JSONP request.
I am still having trouble understanding how I can get a successful request from an API especially from the behance API. I can still see the results in the web dev tools but since what ever I put into my .success block never runs I would appreciate some guidance.
The same code can also be seen in this plunker http://plnkr.co/edit/RZ42Y38BwKZBF2pGZJSR
I've updated your plunker.
You can use for getting any data from Behance API the following code:
angular.module('angularPortfolioApp', ['ngResource']);
angular
.module('angularPortfolioApp')
.factory('behanceUserData', ['$q', '$http',
function($q, $http) {
var service = {
getUser: function(username) {
var d = $q.defer();
$http({
method: 'GET',
url: 'https://www.behance.net/v2/users/USERNAME?api_key=XXX'
}).success(function(data) {
console.log(data);
d.resolve(data);
}).error(function(reason) {
console.log(reason);
d.reject(reason);
});
return d.promise;
}
};
return service;
}
])
.controller('MyController', function($scope, behanceUserData){
$scope.getUser = function(){
$scope.user = behanceUserData.getUser();
}
}
);
And in your view:
<div ng-controller="MyController">
<button ng-click="getUser()">Get</button>
<br/>
{{user | json}}
</div>
Plunker
But you should change this URL: 'https://www.behance.net/v2/users/USERNAME?api_key=XXX' because currently it not works.
I was able to get the data into my model by using the following factory.
.factory('behanceUserData', ['$q', '$http', 'BEHANCE_CLIENT_ID',
function($q, $http, BEHANCE_CLIENT_ID) {
return {
getUser: function(username) {
var q = $q.defer();
$http({
method: 'jsonp',
url: 'http://www.behance.net/v2/users/' + username,
params: {
client_id: BEHANCE_CLIENT_ID,
callback: 'JSON_CALLBACK'
}
}).success(function(data) {
console.log(data);
q.resolve(data);
});
return q.promise;
}
};
}
])

How can I get JSON from an API into a view of my Angular app?

I have a JSON object that is returning at
localhost:9000/api/
and I'd like that JSON data to populate a view at
localhost:9000/#/query
I've got a route
.when('/query', {
templateUrl: 'views/query.html',
controller: 'QueryCtrl'
})
and a controller:
'use strict';
angular.module('myApp')
.controller('QueryCtrl', ['$scope', 'Query', function ($scope, Query) {
$scope.queries = Query.query();
}]);
and the view:
<h1>Queries</h1>
<ul ng-repeat="query in queries">
<li>{{query}}</li>
</ul>
it seems that either "queries" is empty though, or else the view is just not properly connected to the controller.
The app.js also has this factory:
app.factory('Query', ['$resource', function($resource) {
return $resource('/api', null, {
'update': { method:'PUT' }
});
}]);
The JSON object itself looks like this:
[{"tablename":"acc_logs"},{"tablename":"accounts"},{"tablename":"cat_logs"},{"tablename":"err_logs"},{"tablename":"exp_logs"},{"tablename":"pp_logs"},{"tablename":"sec_logs"},{"tablename":"stl_logs"},{"tablename":"tim_logs"},{"tablename":"tom_logs"},{"tablename":"usage_logs"}]
I can see the JSON string at /api, but when I go to /#/query, it is just an empty list.
How can I connect these? What mistake have I made?
EDIT: Thanks for all the help everyone. I forgot to add my controller javascript in index.html. Rookie mistake, took an hour to fix.
I'm seeing that you are calling the Query object that seems to be unavailable, try:
angular.module('myApp')
.controller('QueryCtrl', ['$scope', 'Query', function ($scope, Group) {
$scope.query = Group.query();
Hope this helps.
As I pointed in the comment, you should change $scope.query = Query.query(); to $scope.queries = Query.query();, as you are using ng-repeat over queries.
However, there are another error. You must change
app.factory('Query', ['$resource', function($resource) {
return $resource('/api', null, {
'update': { method:'PUT' }
});
}]);
to
app.factory('Query', ['$resource', function($resource) {
return $resource('/api/query', null, {
'update': { method:'PUT' }
});
}]);
When you call Query.query() you are requesting a HTTP GET to /api, while you want to request to /api/query.

AngularJS - Using $resource and interact with a RESTful data source

I've had a problem in my previous topic, that I couldn't consume my service.
After doing some research I could finally figure out a way to consume my service after all. Still I was wondering why my other approach with the javascript object as method container didn't work out. I have some guesses but can't find an appropriate solution.
Hopefully you guys can lead me on the right path.
controller.js (Working solution)
angular.module('TodoApp.controllers', []).
controller('listCtrl', function ($scope, $location, todoApiService) {
$scope.todos = todoApiService.query();
});
services.js (Working solution)
angular.module('TodoApp.services', []).
factory('todoApiService', function ($resource) {
return $resource('/api/todo/:id', { id: '#id' }, { update: { method: 'PUT' } });
});
controllers.js (Not working solution)
angular.module('TodoApp.controllers', []).
controller('listCtrl', function ($scope, $location, todoApiService) {
$scope.todos = todoApiService.getMyTodos.query();
});
services.js (Not working solution)
angular.module('TodoApp.services', []).
factory('todoApiService', function () {
var todoApi = {};
todoApi.getMyTodos = function ($resource) {
return $resource('/api/todo/:id', { id: '#id' }, { update: { method: 'PUT' } });
};
return todoApi;
});
You should either:
Inject $resource to your factory function, just like you did in the working version. And then you can remove the $resource as a parameter for getMyTodos.
angular.module('TodoApp.services', []).
factory('todoApiService', function ($resource) {
var todoApi = {};
todoApi.getMyTodos = function () {
return $resource('/api/todo/:id', { id: '#id' }, { update: { method: 'PUT' } });
};
return todoApi;
});
And then from the controller:
angular.module('TodoApp.controllers', []).
controller('listCtrl', function ($scope, $location, todoApiService) {
$scope.todos = todoApiService.getMyTodos().query();
});
Or, you can pass the $resource from the controller to getMyTodos (after injecting it to the controller) - so your controller would look like:
angular.module('TodoApp.controllers', []).
controller('listCtrl', function ($scope, $location, todoApiService, $resource) {
$scope.todos = todoApiService.getMyTodos($resource).query();
});
I didn't check to see that this is working, but it should :)

AngularJS - always have a param as a default for a Resource

Basically I got a scenario where the API i'm accessing uses a :groupId as a part of the url in many cases. Is there a easy way to avoid passing $routeParams.groupId in each function call?
var app = angular.module('plunker', []);
app.config(["$routeProvider", function($routeProvider) {
$routeProvider.
when("/:groupId/location", {templateUrl: "partials/location.html", controller: "LocationCtrl"});
}]);
/* Controllers */
app.controller('LocationCtrl', function($scope, $routeParams, Location) {
Location.groupId = $routeParams.groupId; /* Is this even possible? I want to have it available to Location instead of the below*/
Location.query();
Location.query({groupId: $routeParams.groupId});
});
/* Services */
app.service("Location", function($resource, $routeParams) {
return $resource("/api/:groupId/location", {}, {
query: {method: "GET", isArray: true}
});
});
I think you can do this:
app.service("Location", function($resource, $routeParams) {
return $resource("/api/:groupId/location", {groupId:12345}, {
query: {method: "GET", isArray: true}
});
});
I haven't tested it, but I believe that's how the documentation reads
If it's any help, since the above answer didn't work for me, I appended .query to the end of the call.
app.service("Location", function($resource, $routeParams) {
return $resource("/api/:groupId/location", {groupId:'#groupId'})
.query({ groupId: 12345 });
});

Categories