I have a web api which returns IHttpActionResult(myCollection) on Get.
My angular JS controller is has a function :
$scope.loadcollection = function($defer, params) {
console.log("inside loadcollection ");
mySvc.getCollection().then(function(myCollection) {
//$defer.resolve(myCollection);
$scope.recievedCollection= myCollection
console.log("invoices are : ", $scope.recievedCollection);
});
My service in angular JS is as follows :
app.factory('mySvc', ['$resource', '$q', 'serviceHelperSvc',
function($resource, $q, serviceHelper) {
var myObject= serviceHelper.collectionObj;
var getCollection= function() {
/* var d = $q.defer();
var resp = Invoice.query();
console.log("resp is : ", resp);
d.resolve(true);
return d.promise;*/
return myObject.query();
};
}]);
my serviceHelperSvc is as follows:
app.factory('serviceHelperSvc', ['$http', '$resource',
function($http, $resource) {
var config = {
"apiurl": "http://localhost:8000/"
}
var baseUrl = config.apiurl;
var buildUrl = function(resourceUrl) {
return baseUrl + resourceUrl;
};
var addRequestHeader = function(key, value) {
};
return {
AuthorizationToken: $resource(buildUrl("Token"), null, {
requestToken: {
method: 'POST',
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
}
}),
collectionObj: $resource(buildUrl('api/CollectionObj/:CollectionObjId'), {
CollectionObjId: '#Id'
}, {
'update': {
method: 'PUT'
}
})
};
}
]);
when i try to run this, i get undefined is not a function at mySvc.getCollection().then(function(myCollection)
before then(function(myCollection).
when i try using the defer promise approach, i get an exception at the same place saying $promise is not defined
Related
I am using Angurlar.js to call my Web API and I am getting error as:
P01:1 Uncaught SyntaxError: Unexpected token : and in resources tab it is being shown that these braces should not be there {"ProductID1":"P01","ProductName1":"Pen","Quantity1":10,"Price1":12.0} kindly help me
this is my angular code:
var app = angular.module('store', []);
app.controller('StoreController', ['$http', '$scope', function ($http, $scope) {
$scope.display = function () {
// $http.get('http://localhost:17279/api/Product/GetProduct/' + $scope.pid).success(function (data) {
$http({
method: 'jsonp',
url: 'http://localhost:17279/api/Product/GetProduct/' + $scope.pid,
params: {
format: 'jsonp',
json_callback: 'JSON_CALLBACK'
}
}).success(function (data) {
{{data}}
});
}
}]);
below code is in my WebAPI controller
List<Product> productList = new List<Product>{
new Product{ProductID1="P01",ProductName1="Pen",Quantity1=10,Price1=12},
new Product{ProductID1="P02",ProductName1="Copy",Quantity1=12,Price1=20},
new Product{ProductID1="P03",ProductName1="Pencil",Quantity1=15,Price1=22},
new Product{ProductID1="P04",ProductName1="Eraser",Quantity1=20,Price1=27},
};
public List<Product> GetProductList()
{
return productList;
}
public IHttpActionResult GetProduct(string id)
{
var product = productList.FirstOrDefault(
(p) => p.ProductID1 == id);
if(product == null)
{
return NotFound();
}
return Ok(product);
}
Apart from this I have a product model class in WebAPI which has 4 members and their properties namely : price,quantity,productID,productname
Remove the {{data}} in your success callback. This is angular's way of binding expressions to view and should not be used within your javascript code
$scope.display = function () {
$http({
method: 'jsonp',
url: 'http://localhost:17279/api/Product/GetProduct/' + $scope.pid,
params: {
format: 'jsonp',
json_callback: 'JSON_CALLBACK'
}
}).then(function (data) {
$scope.data = data;
});
}
I have this service :
(function() {
'use strict';
angular
.module('myApp')
.factory('Consultant', Consultant);
Consultant.$inject = ['$resource', 'DateUtils'];
function Consultant ($resource, DateUtils) {
var resourceUrl = 'api/consultants/:id';
return $resource(resourceUrl, {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET',
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
},
'update': {
method: 'PUT',
transformRequest: function (data) {
return angular.toJson(data);
},
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
},
'save': {
method: 'POST',
transformRequest: function (data) {
return angular.toJson(data);
},
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
}
});
}
})();
What if I want to add the url api/consultantscustom/:id (with its query/get/update methods) to this service?
As it seems that this file can contain only one factory, is there a way to do that or do I need to create another file with a new factory?
Maybe I am totally misunderstanding what you are asking, but you can have as many factories in one file as you like (or as seems useful):
(function() {
'use strict';
angular.module('myApp')
.factory('Consultant', Consultant)
.factory('Custom', Custom);
Consultant.$inject = ['$resource', 'DateUtils'];
Custom.$inject = ['$resource'];
function Consultant ($resource, DateUtils) {
var resourceUrl = 'api/consultants/:id';
...
}
function Custom ($resource) {
var resourceUrl = 'api/consultantscustom/:id';
...
}
Or, if you want to re-use the same factory to access different URLs, you could add methods to set the URL and then re-use the call to the generic resource.
function Consultant ($resource, DateUtils) {
function consultants () {
_call_resource('api/consultants/:id');
}
function custom () {
_call_resource('api/consultantscustom/:id');
}
function _call_resource (resourceUrl) {
return $resource(resourceUrl, {}, {
...
}
}
this.consultants = consultants;
this.custom = custom;
return this;
}
I have this code in my post.serv.js and in my controller I want to execute the function delete.
"use strict";
app.factory('JnttPost', function ($resource) {
var PostResource = $resource('/api/post/:_id', {
_id: "#id"
}, {
update: {
method: 'PUT',
isArray: false
}
}, {
delete: {
method: 'DELETE',
isArray: false
}
});
return PostResource;
});
I already know how to get and update a post, for example in my createpost.serv.js
"use stric";
app.factory('JnttCreatePost', function ($http, $q, JnttPost) {
return {
createPost: function (newPostData) {
var newPost = new JnttPost(newPostData);
var dfd = $q.defer();
newPost.$save().then(function () {
dfd.resolve();
}, function (response) {
dfd.reject(response.data.reason);
});
return dfd.promise;
}
};
});
and in my newpost.ctrl.js
"use strict";
app.controller('CtrlNewPost',
function ($scope, $location, JnttIdentity, JnttNotifier, JnttCreatePost) {
var email = ...;
$scope.newPost = function () {
var newPostData = {...};
JnttCreatePost.createPost(newPostData).then(function () {
JnttNotifier.notify('success', 'The post has been created');
$location.path('/');
}, function (reason) {
JnttNotifier.notify('error', reason);
});
};
});
I can't realize how to perform the delete request, I can do with a $http
In my new controller for do deletePost() function I have this:
$scope.deletePost = function () {
var pwd = JnttIdentity.currentUser.hashed_pwd;
var postidd = {
password: pwd,
id: $scope.post._id
};
var config = {
method: "DELETE",
url: '/api/post/',
data: postidd,
headers: {
"Content-Type": "application/json;charset=utf-8"
}
};
$http(config);
$location.path('/');
};
This actually already do this stuff but I want to do this without the $http like the create request, How I can do this? How do I can edit this code below for do the request?
createPost: function (newPostData) {
var newPost = new JnttPost(newPostData);
var dfd = $q.defer();
newPost.$save().then(function () {
dfd.resolve();
}, function (response) {
dfd.reject(response.data.reason);
});
return dfd.promise;
}
In my routes.js in express I have this route:
app.delete('/api/post/', posts.deletePost);
You can either call delete on the $resource class you create (JnttPost) or call $delete on a post that's returned from the $resource class.
The $resource class already has get/save/query/remove/delete functions included so you don't need to add the delete (save is create/POST, so you need to include update with PUT).
Here's a sample of using your $resource class to call delete:
angular.module('test', ['ngResource'])
.factory('JnttPost', function ($resource) {
var PostResource = $resource('/api/post/:_id', {
_id: "#id"
}, {
update: {
method: 'PUT',
isArray: false
}
});
return PostResource;
})
.run(function(JnttPost){
JnttPost.delete({id: 123123123});
});
I have tried to build a service that will return a $resource after the service has authenticated.
I have done it like this:
.factory('MoltinApi', ['$q', '$resource', '$http', 'moltin_options', 'moltin_auth', function ($q, $resource, $http, options, authData) {
var api = $resource(options.url + options.version + '/:path', {
path: '#path'
});
var authenticate = function () {
if (!options.publicKey)
return;
var deferred = $q.defer();
var request = {
method: 'POST',
url: options.url + 'oauth/access_token',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: "grant_type=implicit&client_id=" + options.publicKey
};
$http(request).success(function (response) {
authData = response;
deferred.resolve(api);
});
return deferred.promise;
};
return authenticate();
}])
But I can not call the resource in my controller:
.controller('HomeController', ['MoltinApi', function (moltin) {
var self = this;
moltin.get({ path: 'categories' }, function (categories) {
console.log(categories);
});
}]);
it just states that 'undefined is not a function'.
Can someone tell me what I am doing wrong?
Update 1
So after playing with the solution that was suggested, this is the outcome.
angular.module('moltin', ['ngCookies'])
// ---
// SERVICES.
// ---
.factory('MoltinApi', ['$cookies', '$q', '$resource', '$http', 'moltin_options', function ($cookies, $q, $resource, $http, options) {
var api = $resource(options.url + options.version + '/:path', {
path: '#path'
});
var authenticate = function () {
if (!options.publicKey)
return;
var deferred = $q.defer();
var authData = angular.fromJson($cookies.authData);
if (!authData) {
console.log('from api');
var request = {
method: 'POST',
url: options.url + 'oauth/access_token',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: "grant_type=implicit&client_id=" + options.publicKey
};
deferred.resolve($http(request).success(function (response) {
$cookies.authData = angular.toJson(response);
setHeaders(response.access_token);
}));
} else {
console.log('from cookie');
deferred.resolve(setHeaders(authData.access_token));
}
return deferred.promise;
};
var setHeaders = function (token) {
$http.defaults.headers.common['Authorization'] = 'Bearer ' + token;
}
return authenticate().then(function (response) {
return api;
});
}]);
and to call it I have to do this:
.controller('HomeController', ['MoltinApi', function (moltin) {
var self = this;
moltin.then(function (api) {
api.get({ path: 'categories' }, function (categories) {
console.log(categories);
self.sports = categories.result;
});
});
}]);
but what I would like to do is this:
.controller('HomeController', ['MoltinApi', function (moltin) {
var self = this;
moltin.get({ path: 'categories' }, function (categories) {
console.log(categories);
}, function (error) {
console.log(error);
});
}]);
As you can see, the service is checking to see if we have authenticated before returning the API. Once it has authenticated then the API is returned and the user can then call the api without having to authenticate again.
Can someone help me refactor this service so I can call it without having to moltin.then()?
You are returning the authenticate function call in the MoltinApi factory, so you are returning the promise. And the method get doesn't exist in the promise
myapp.factory('serviceName', function( $http, webStorage){
var factory = {};
var resoureurlBase=some base url;
factory.genericService = function(method, payload, methodName, callbackFn, callbackError, param) {
var httpRequest = null;
if (param && param == true) {
httpRequest = $http({
url: resoureurlBase+methodName,
method: method,
params: payload,
headers: {
'Content-Type': 'application/json'
}
});
} else {
httpRequest = $http({
url: resoureurlBase+methodName,
method: method,
data: payload,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
}
httpRequest.then(function(response) {
if (callbackFn && callbackFn.call) {
callbackFn.call(null, response);
}
},
function(response) {
if (callbackError && callbackError.call) {
callbackError.call(response);
}
});
httpRequest.error(function(data, status, headers, config) {
});
};
return factory;
});
/*
I have written service like above how can i handle in controller
i mean
how to write call back function in controller
how to inject
etc..
*/
Simple DI(dependency injection) it into your controller:-
myapp.controller('myCtrl',['$scope','serviceName',function($scope,serviceName){
// use serviceName to call your factory function
}]);
Ref:- https://docs.angularjs.org/guide/di
You need to call service like
serviceName.genericService(--parmas--).then(function(d){
//success
})
because from service serviceName, you're returning a promise that need to resolved using .then only.
Controller
var mainController = function($scope, serviceName) {
var callbackFn = function() {
console.log('Success');
}
var callbackError = function() {
console.log('Error');
}
var parameter = {
param1: 1
},
method = 'something', payload = 100, methodName = 'something';
serviceName.genericService(method, payload, methodName, callbackFn, callbackError, parameter).then(
//success function
function(data) {
//call after call succeed
},
//error function
function(error) {
//call after call error
});
};
myapp.controller('mainController', ['$scope', 'serviceName', mainController()];
Hope this could help you. Thanks.