$http GET array of objects from an api - angularjs

Below is my AirTableService.js
(function () {
"use strict";
var AirTableService = function ($http, $q) {
var AirTableMethods = {
getMyRounds: function(AirTable_secret){
var deferObject_myRounds;
var myRounds_promise = $http.get('https://api.airtable.com/v0/XXXXXXX/Rounds?view=Main%20View&maxRecords=10&callback=JSON_CALLBACK', {
headers : {
'Authorization' : AirTable_secret.apikey,
'Content-Type' : 'application/json'
}
});
deferObject_myRounds = deferObject_myRounds || $q.defer();
myRounds_promise.then(function(data){
deferObject_myRounds.resolve(data);
});
return deferObject_myRounds.promise;
}
};
return AirTableMethods;
};
AirTableService.$inject = ['$http', '$q'];
angular.module('appGolf')
.service('AirTableService', AirTableService);
}());
In there as you can see, using AirTable's api I am trying to GET data from my table. I'm passing the parameters view and maxRecords and it works.
Documentation states I can pass sort,
which I then changed to,
https://api.airtable.com/v0/XXXXXXX/Rounds?view=Main%20View&maxRecords=10&sort=[{field:'RoundID',direction:'desc'}]&callback=JSON_CALLBACK
and clearly that doesn't work and it it gives me this error,
I know this is because sort is a array of objects and I know how I am passing this is incorrect.
My question is, how do you do this in AngularJS?
Thank you in advance.

Found the answer here
As mentioned there, I needed to add,
paramSerializer: '$httpParamSerializerJQLike',
And if you are interested, my function now looks like,
var myRounds_promise = $http.get('https://api.airtable.com/v0/XXXXX/Rounds?callback=JSON_CALLBACK', {
params: {
view: 'Main View',
maxRecords: 10,
sort: [{"field": 'RoundID', "direction":'desc'}]
},
paramSerializer: '$httpParamSerializerJQLike',
headers : {
'Authorization' : AirTable_secret.apikey,
'Content-Type' : 'application/json'
}
});
Thanks everyone for their suggestions and helping me out.

Your service is very verbose and hard to read. I would write it like this:
var app = angular.module("myApp", [ /* dependencies */ ]);
app.factory("AirTableService", ["$http", function($http) {
return {
getMyRounds: function(AirTable_secret) {
return $http.get('path/to/API', {
//put your sorting JSON object here in params
params: { sort: [{field: "RoundID", direction: "desc"}] },
headers: {
'Authorization' : AirTable_secret.apikey,
'Content-Type' : 'application/json'
}
});
},
anotherMethod: function() {
//etc....
},
yetAnotherMethod: function() {
return $http.post(); //maybe POST something
}
};
}]);
Inject it to your controller and use:
AirTableService.getMyRounds(airtableSecret).then(successCallback).catch(errorCallback);

Related

How to instantiate angular service with multiple resources?

I have an angular service based on meanjs for rents. Originally it looked like this:
(function () {
'use strict';
angular
.module('rents.services')
.factory('RentsService', RentsService);
RentsService.$inject = ['$resource', '$log'];
function RentsService($resource, $log) {
var Rent = $resource(
'/api/rents/:rentId',
{
rentId: '#_id'
},
{
update: {
method: 'PUT'
},
getByCarId:
{
method: 'POST',
params: {
rentId: 'bycar'
},
isArray: true,
hasBody: true,
requestType: 'json',
responseType: 'json'
}
}
);
angular.extend(Rent.prototype, {
createOrUpdate: function () {
var rent = this;
return createOrUpdate(rent);
}
});
return Rent;
// and all other function that are the same as down below
}());
Then I added a second resource
(function () {
'use strict';
angular
.module('rents.services')
.factory('RentsService', RentsService);
RentsService.$inject = ['$resource', '$log'];
function RentsService($resource, $log) {
var Rent =
{
basic: $resource(
'/api/rents/:rentId',
{
rentId: '#_id'
},
{
update: {
method: 'PUT'
},
getByCarId:
{
method: 'POST',
params: {
rentId: 'bycar'
},
isArray: true,
hasBody: true,
requestType: 'json',
responseType: 'json'
}
}
),
carUsageStats: $resource(
'/api/rents/car_usage'
)
};
angular.extend(Rent.basic.prototype, {
createOrUpdate: function () {
var rent = this;
return createOrUpdate(rent);
}
});
return Rent;
function createOrUpdate(rent) {
if (rent._id) {
return rent.$update(onSuccess, onError);
} else {
return rent.$save(onSuccess, onError);
}
// Handle successful response
function onSuccess(rent) {
// Any required internal processing from inside the service, goes here.
}
// Handle error response
function onError(errorResponse) {
var error = errorResponse.data;
// Handle error internally
handleError(error);
}
}
function handleError(error) {
// Log error
$log.error(error);
}
}
}());
Until I added second resource, this resolve function for creating new rent worked fine
newRent.$inject = ['RentsService'];
function newRent(RentsService) {
return new RentsService();
}
But when I added second resource (and had to address the one I want by using property name - cant use Rent.query() but Rent.basic.query()) instantiating new Rent no longer works. I added console log outputs around and code stops executing at line var rent = new RentsService(). Querying works fine. What is the correct way of making new object using service with multiple resources?

$cancelRequest is not a function

I'm using angularjs 1.5.8.
I get this error when I'm trying to cancel an http request with angular :
$cancelRequest is not a function
My code :
app.factory('User', function($resource) {
var getUsersResource = $resource(
'/users',
null,
{get : {method: 'GET', isArray: true, cancellable: true}}
);
return {
getUsers : function() {
return getUsersResource.get({},
function(data) {
...
}, function(error) {
...
}
);
}
};
});
app.controller('InitController', function($rootScope, User, ...) {
...
User.getUsers();
...
}
app.factory('AuthInterceptor', function($q, $location, $injector) {
return {
responseError: function(response) {
if (response.status === 401) {
$injector.get('$http').pendingRequests.forEach(
function (pendingReq) {
pendingReq.$cancelRequest();
}
);
$location.path('login');
}
return $q.reject(response);
}
};
});
Do you know how I can solve this error ?
Thanks
The documentation suggests that $cancelRequest should be used with the resource object. From my initial review, it appears that you're correctly using $resource within the User factory. But, I'm not sure about how you're implementing this within the AuthInterceptor factory. It doesn't look like you're using User.getUsersSources() at all. Therefore, I believe the reason that you're getting that error is because you're not using $cancelRequestion correctly. That being said, you might have forgotten to include other parts of the code.
Ideally, the resolved $resource object from User.getUserResources() should be passed into AuthInteceptor.
I think that you should declare your service like that:
.factory('categoryService', ['$resource', function($resource) {
return $resource('/', {},
{
'get': {
'method': 'GET',
'cancellable': true,
'url': '/service/categories/get_by_store.json',
},
});
}])
And when you use this service, it should be called so:
if ( $scope.requestCategories ) {
$scope.requestCategories.$cancelRequest();
}
$scope.requestCategories = categoryService['get']({
}, function(res){
//some here
}, function(err){
//some here
});

How update APi with AngularJS?

I create a simple single page application with angularJS and laravel , , the method get, delete and store created , now how create the update method in my code?
I use below link in my app
https://scotch.io/tutorials/create-a-laravel-and-angular-single-page-comment-application
var app = angular.module('app',['ui.bootstrap'],function($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
app.factory('Depot', function($http) {
return {
get : function() {
return $http.get('depots/depot');
},
save : function(commentData) {
return $http({
method: 'POST',
url: 'depots/depot',
headers: { 'Content-Type' : 'application/x-www-form-urlencoded' },
data: $.param(commentData)
});
},
destroy : function(depot_number) {
return $http.delete('depots/depot/' + depot_number);
}
}
});
app.controller('appCtrl', function($scope, $http, Depot) {
$scope.commentData = {};
$('#show_success').hide();
$('#show_remove').hide();
Depot.get()
.success(function(data) {
$scope.comments = data;
});
$scope.submitComment = function() {
Depot.save($scope.commentData)
.success(function(data) {
Depot.get()
.success(function(getData) {
$('#add_depot').hide();
$('#depot_name').val('');
$('#have_id').removeAttr('checked');
$('#show_success').show();
setTimeout(function() {
$('#show_success').hide();
},1500);
$scope.comments = getData;
});
})
.error(function(data) {
console.log(data);
});
};
$scope.deleteComment = function(id) {
Depot.destroy(id)
.success(function(data) {
Depot.get()
.success(function(getData) {
$('#show_remove').show();
setTimeout(function() {
$('#show_remove').hide();
},1500);
$scope.comments = getData;
});
});
};
});
You should read up on the documentation for ngResource. This is by far your best bet for a RESTful application.
I have answered another question a bit more detailed, perhaps it could help you too?
We really do need your endpoints / server-code to help you more.

Is it possible so send just a part of an object by angular resource?

I have a resource where the get is receiving an object like {metadata : {}, data : {}}. But when I save, I just want to send the data and not metadata.
.factory("$profile", function($resource) {
return $resource("service/profile/:profileid");
})
.controller('ProfileController', function($scope, $routeParams, $profile) {
$scope.profile = new $profile();
$scope.doSave = function() {
// need to send profile.data only << ----------
$scope.profile.$save($routeParams, function(data) {
console.log("saved profile");
});
}
What I have done right now is the following:
.controller('ProfileController', function($scope, $routeParams, $profile) {
$scope.profile = new $profile();
$scope.doSave = function() {
$scope.profile.data.$save = $scope.profile.$save;
$scope.profile.data.$save($routeParams, function(data) {
console.log("saved profile");
});
}
This works but I am sure there is a much cleaner way to do what I need to do. Ideally I would tell the resource to look for a data property on "save".
Yes, you can do that. The properties you need are 'transformResponse' (on GET) and 'transformRequest' (on Post).
.factory("$profile", function($resource) {
return $resource("service/profile/:profileid",
{},
{
get: {
method: 'GET',
transformResponse: function(response, headers){
return response.data;
}
},
post: {
method: 'POST',
transformRequest: function (request, headers) {
var result = request.data; // << This line might not be exactly what you need.
return result;
}
}
});
})
I actually suspect that the transformRequest part isn't needed at all (but you did ask for it).
$scope.profile.$save($routeParams, function(data) {
console.log("saved profile");
});

how to make Generic method for rest call in angularjs

how to make Generic method for rest call in angularjs ?
i have tried for single request, it's working fine
UIAppRoute.controller('test', ['$scope', 'checkStatus', function($scope, checkStatus) {
$scope.data = {};
checkStatus.query(function(response) {
$scope.data.resp = response;
});
}])
UIAppResource.factory('checkStatus', function($resource){
return $resource(baseURL + 'status', {}, {'query': {method: 'GET', isArray: false}})
})
I want to make this as generic for all the request
Please share any sample,.. thanks in advance
I'm using something like this :
.factory('factoryResource', ['$resource', 'CONF',
function($resource, CONF) {
return {
get: function(endPoint, method) {
var resource = $resource(CONF.baseUrl + endPoint, {}, {
get: {
method: method || 'GET'
}
});
return resource.get().$promise;
}
};
}
])
called by :
factoryResource.get(CONF.testEndPoint, "POST"); // make a POST and return a promise and a data object
factoryResource.get(CONF.testEndPoint, "GET"); // make a GETand return a promise and a data object
factoryResource.get(CONF.testEndPoint); // make a GETand return a promise and a data object
with a config file having :
angular.module('app.constant', [])
.constant('CONF', {
baseUrl: 'http://localhost:8787',
testEndPoint: '/api/test'
});

Resources