how to build angular $resource POST request to server? - javascript

I can't catch request on ASP.NET MVC project on server side controller from AngularJS:
var appDirective = angular.module('app.directive', []);
var xmplService = angular.module('app.service', ['ngResource']);
var appFilter = angular.module('app.filter', []);
var app = angular.module('app', ['app.service', 'app.directive', 'app.filter', 'solo.table']);
xmplService
.factory('testResource1', function ($resource) {
return $resource('/SoloAngularTable/TestMethod3', { id: '#id' }, { charge: { method: 'POST' } });
});
app
.controller('ContentPlaceHolder1Controller', function ($scope, $http, testResource1) {
testResource1.find({ id: 123 }, function (data) {
alert('success');
});
});
On MVC Controller I have a method that can't catch request:
[HttpPost]
public JsonResult TestMethod3(int id)
{
var data = new { User = "Alex" };
return Json(data);
}
How to build simple request to server side with AngularJS $resource and catch request?

find is not a default action for $resource. The defaults are:
{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
You will have to create/specify the find action. You are currently creating/specifying a charge action. Perhaps this is what you meant to use?
If you want to use find, here is the fix:
.factory('testResource1', function ($resource) {
return $resource('/SoloAngularTable/TestMethod3', { id: '#id' }, {
charge: { method: 'POST' },
find: { method: 'POST' } // Added `find` action
});
});
If you meant to use charge, here is the fix:
.controller('ContentPlaceHolder1Controller', function ($scope, $http, testResource1) {
testResource1.charge({ id: 123 }, function (data) {
alert('success');
});
});

Related

Angular throwing exception 'module cant be loaded'!

I was trying to clean my angular app code up. So I moved all the controllers in their own files. But when I moved the controllers, my main app stoped working and started throwing the exception below -
Error: $injector:modulerr
Module Error
Then I tried searching for the why the module won't load but with no luck.
main.js /*File where app module is declared*/
var app = angular.module('app', ['ngRoute','thatisuday.dropzone','UserController','LinkController','articleController']);
I tried injecting the dependency for the controller files.
Controllers:
Link Controller
var app = angular.module('app');
app.controller('LinkController', ['$scope','$http','$sce',function ($scope, $http, $sce) {
/*Sce declaration required for proxy settings*/
$scope.renderHtml = function (html_code) {
return $sce.trustAsHtml(html_code);
};
$scope.trustSrc = function (src) {
return $sce.trustAsResourceUrl(src);
};
/*First AJAX request which gets all the links and categories for the user*/
$http({
method: 'GET',
url: '/users'
}).then(function successCallback(response) {
$scope.user = response.data;
}, function errorCallback(response) {
});
$scope.getUser = function () {
$http({
method: 'GET',
url: '/users'
}).then(function successCallback(response) {
$scope.user = response.data;
}, function errorCallback(response) {
});
};
$http({
method: 'GET',
url: '/links'
}).then(function successCallback(response) {
this.orderProp = 'age';
/*the response is saved in scope variables*/
$scope.links = response.data[0];
$scope.categories = response.data[1];
$scope.categorytolink = response.data[2];
}, function errorCallback(response) {
console.log('There was a problem! Refresh!');
});
/*AJAX request for getting the recommendations according to the most viewed stars*/
$http({
method: 'GET',
url: '/recommendations/top'
}).then(function successCallback(response) {
$scope.recommendations = response.data;
}, function errorCallback(response) {
});
/*AJAX request when a user clicks a link retrieves the link data*/
$scope.getLinkData = function (link) {
$http({
method: 'GET',
url: "/proxy",
headers: {
"X-Proxy-To": link.rss_link
}
}).then(function successCallback(response) {
/*AJAX request: add a star to the link*/
$http.post('/links/' + link.id + '/views/add', {'link': link}).then(function successCallback(data, status, headers, config) {
// Manually increment star for link just clicked
var $data;
$data = data.data;
$scope.link = $data;
console.log('200 OK! Star added');
}, function errorCallback() {
console.log('Error!');
});
/*The data will be retrieved and will be sorted according to the requirements of welcome.blade*/
$myXml = response.data;
$xmlObj = $.parseXML($myXml);
$newsItems = [];
$channelImage = $($xmlObj).find("channel>image");
/*the information of the link is sorted */
$linkData = {
"title": $channelImage.find("title").text(),
"link": $channelImage.find("link").text(),
"imgurl": $channelImage.find("url").text()
};
/*the data is sorted below*/
$.each($($xmlObj).find("item"), function (index, value) {
$newsItems.push({
"title": $(value).find("title").text(),
"description": $(value).find("description").text(),
"link": $(value).find("link").text(),
"date_published": moment($(value).find("pubDate").text()).format('MMMM Do YYYY'),
"time_published": moment($(value).find("pubDate").text()).format('h:mm:ss a'),
"guid": $(value).find("guid").text()
})
});
$scope.newsItems = $newsItems;
$scope.linkData = $linkData;
}, function errorCallback(response) {
});
};
/*Create a category private to the user*/
$scope.create_category = function (category) {
/*AJAX request: adds a new category*/
$http.post('/categories/new', {'category': category}).then(function successCallback(response) {
/*AJAX request: Updates the categories for the use of new category*/
$http({
method: 'GET',
url: '/categories'
}).then(function successCallback(response) {
$scope.categories = response.data;
}, function errorCallback(response) {
});
}, function errorCallback(response) {
});
};
}]);
User Controller
var app = angular.module('app');
app.controller("UserController", ['$scope','$http','$sce', function ($scope, $http, $sce) {
/*Sce declaration required for proxy settings*/
$scope.renderHtml = function (html_code) {
return $sce.trustAsHtml(html_code);
};
$scope.trustSrc = function (src) {
return $sce.trustAsResourceUrl(src);
};
$scope.dzOptions = {
paramName: "file",
dictDefaultMessage: "<h4><i class='fa fa-camera'></i> <b>Upload</b></h4>",
createImageThumbnails: false,
autoDiscover: false
};
$scope.dzCallbacks = {
'sending': function (file, xhr, formData) {
formData.append('_token', $('#csrf-token').val());
},
'success': function (file, response) {
$scope.user = response;
$.notify("Profile photo changed!", "success", {autoHide: true, autoHideDelay: 500});
}
};
/*Update user info*/
$scope.updateUser = function () {
/*AJAX request: update user info*/
$http.post('/users/update', {
'name': $scope.user.name,
'username': $scope.user.username,
'email': $scope.user.email
}).then(
function successCallback(data) {
$scope.user = data;
$.notify("User updated!", "success", {autoHide: true, autoHideDelay: 500});
console.log('200 OK! User updated');
}, function errorCallback() {
console.log('Error!');
});
};
}]);
Article Controller
var app = angular.module('app');
app.controller("articleController", ['$scope','$http','$sce', function ($scope, $http, $sce) {
/*Sce declaration required for proxy settings*/
$scope.renderHtml = function (html_code) {
return $sce.trustAsHtml(html_code);
};
$scope.trustSrc = function (src) {
return $sce.trustAsResourceUrl(src);
};
/*Populates the comments for particular
* */
$scope.populatecomments = function (newsItem) {
$http({
method: 'GET',
url: '/articles/' + newsItem.guid + '/comments'
}).then(function successCallback(response) {
$scope.comments = response.data;
}, function errorCallback(response) {
});
};
$scope.data = [];
$scope.comment = [];
$scope.btn_add = function (newsItem) {
if ($scope.txtcomment != '') {
$scope.data.push({
"comment": $scope.txtcomment,
"guid": newsItem.guid
});
$http.post('/comments/new', {
"comment": $scope.txtcomment,
"guid": newsItem.guid
}).then(function successCallback() {
var encodedURI = encodeURIComponent(newsItem.guid);
$http({
method: 'GET',
url: '/articles/' + encodedURI + '/comments'
}).then(function successCallback(response) {
$scope.comments = response.data;
$scope.txtcomment = "";
}, function errorCallback(response) {
});
}, function errorCallback() {
console.log('Error comment!');
});
}
};
$scope.savearticle = function (newsItem) {
$http.post('/saved-articles/save', newsItem).then(function successCallback(response) {
/*console.log(document.getElementById("save/"+newsItem.guid).className="disabled");*/
}, function errorCallback(response) {
});
}
/**
* The saved articles by the user will be retrieved when a button clicked
*/
$scope.getSavedArticles = function () {
/*AJAX request: retreive the saved the saved articles for the user*/
$http({
method: 'GET',
url: '/saved-articles'
}).then(function successCallback(response) {
$scope.linkData = null;
$scope.newsItems = response.data;
}, function errorCallback(response) {
});
};
}]);
HELP needed!
Yo do not need to declare module in each controller file. Remove the line in each controller
var app = angular.module('app');
You are injecting controller in you module like dependency.
Change your main.js file to this:
var app = angular.module('app', ['ngRoute','thatisuday.dropzone']);
#Sajeetharan is right you do not need module declaration in all controllers.
Since you are using laravel according to your comment. ( It will conflict with your blade template because both use same {{ }} for variables )
There are two ways to do this:
Change the Angular Tags
var app = angular.module('app', [], function($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
Now Laravel will use the {{ variableName }} and Angular will use <%
variableName %>.
Change the Laravel Blade Tags
Blade::setContentTags('<%', '%>');// for variables and all things Blade
Blade::setEscapedContentTags('<%%', '%%>');// for escaped data
Variables will be: <% $variable %>. Comments will be: <%-- $variable
--%>. Escaped data will look like: <%% $variable %%>.
You can check this Tutorial for more info.

Passing complex object from angular js factory to web api using $resource

I am passing an object to angular factory it is throwing error.
factory:
visitorApp.factory('loginRepository', function ($resource) {
return {
VerifyVisitor: $resource('/api/VisitorWeb/VerifyLogin', {}, {
query: { method: 'POST', params: {loginModel:loginModel}, isArray: true }
})
};
});
The complex object i am trying to pass is loginModel.
From controller call to factory.
visitorApp.controller('LoginController', function ($scope,$location,$route,loginRepository) {
$scope.submit = function (isValid) {
if (isValid) {
var loginModel = {
UserName: $scope.UserName,
PassWord: $scope.Password
};
var response = loginRepository.VerifyVisitor.query(loginModel);
alert(response);
}
}
});
Error: loginModel is not defined
Web Api Method which is being called.
[HttpPost]
public string VerifyLogin(UserLoginDomainModel loginModel)
{
var msg = _loginService.Login(loginModel);
return msg;
}
Is it the right way of using $resource to post a request and pass complex object.
Your service should look something like this:
visitorApp.factory('loginRepository', function ($resource) {
return {
VerifyVisitor: $resource('/api/VisitorWeb/VerifyLogin', {},
{
query: {
method: 'POST',
params: {loginModel: '#loginModel'},
isArray: true }
})
};
});
The parameter variables are enclosed in quotes and prefixed with an #.

Problems when passing parameters of an Angular application for a Rails controller

I have an application made in angularjs, but I'm having trouble reading the parameters on the server side.
As I'm sending the data:
api.factory('AuthProvider', function($resource, ENV){
var baseUrl = ENV.apiEndpoint;
return $resource(baseUrl, null,
{
login: {
method: 'POST',
url: baseUrl+'sessions'
}
});
});
angular.module('tuneduc.controllers.admin',[])
.controller('AdminController', function($scope, $location, AuthProvider) {
var auth;
$scope.login = function (credentials) {
auth = new AuthProvider(credentials)
auth.$login(function(res) {
console.log('success');
},
function(res) {
console.log(res.data.errors);
})
}
});
So the parameters are coming this way on the server:
{"{\"email\":\"assdaf#adfasdf.com\",\"password\":\"sadfsdf\"}"=>nil, "controller"=>"sessions", "action"=>"create"}
I've tried using JSON.stringify () but failed.

AngularJS Resource with relation between tables

is this possible with AngularJS Resource?
/api/client/:id/jobs (get all the jobs from this client)
/api/client/:id/job/:jobId (get the job form this client)
My Factory:
.factory('Client', ['$resource', 'Api',
function ($resource, Api) {
var Client = $resource(Api.url() + 'client/:id/',
{
id: '#id'
},
{
'update' : { method: 'PUT', isArray: false }
}
);
return Client;
}
]);
Thanks!
I found a solution for my problem.
I have to create another factory to do the job:
.factory('ClientJobs', ['$resource', 'Api',
function ($resource, Api) {
var ClientJobs = $resource(Api.url() + 'client/:clientId/job/:jobId',
{
clientId: '#Id',
jobId: '#Id'
},
{
'query': { method: 'GET', isArray: true },
'update': { method: 'PUT' }
}
);
return ClientJobs;
}
]);
And, i can use the factory like this:
ClientJobs.save({clientId:clientId, jobId:job.id}, job, function (result) {
deferred.resolve(result);
}, function (reason) {
deferred.reject(reason);
});
Now, everything is working.
And for help those people who are working with UI-ROUTER, there is this question with an excellent answer about complex states like mine and nested views:
Nested Views with Nested States

AngularJS $resource & cache factory

I have implemented angular $resource with custom functions and parameters as follows:-
.factory('CandidateService', ['$resource', function ($resource) {
return $resource("api/:action/:id", {},
{
'getCandidates': { method: "GET", params: { action: "Candidate" }, isArray: true },
'getCandidate': { method: 'GET', params: { action: "Candidate", id: "#id" } }
});
}]);
And I am consuming this in the controller as follows:-
.controller('Controller', ['CandidateService', function ($scope, CandidateService) {
$scope.candidateList = [];
CandidateService.getAll(function (data) {
$scope.candidateList = data;
});
}]);
This is working absolutely fine. Now I need to cache the data from the api into the CandidateService Factory so it is not loaded eveytime I move between the controllers.
So I thought i would do something as follows:-
.factory('CandidateService', ['$resource', function ($resource) {
var Api = $resource("api/:action/:id", {},
{
'getCandidates': { method: "GET", params: { action: "Candidate" }, isArray: true },
'getCandidate': { method: 'GET', params: { action: "Candidate", id: "#id" } }
});
var candidateDataLoaded = false;
var candidateData = [];
return {
getCandidates: function () {
if (!candidateDataLoaded) {
Api.getAll(function (data) {
angular.copy(data, candidateData);
});
}
return candidateData;
}
}
}]);
But I just cant get this to work. I think it has something to do with angular factory being a singleton.
Is my approach correct to implement the caching?
You can use the $cacheFactory object.
See : http://docs.angularjs.org/api/ng.$cacheFactory
You can cache $http request like that :
var $httpDefaultCache = $cacheFactory.get('$http');
If you want to retrieve a specific url in cache do :
var cachedData = $httpDefaultCache.get('http://myserver.com/foo/bar/123');
$You can clear the cache too :
$httpDefaultCache.remove('http://myserver.com/foo/bar/123');
or :
$httpDefaultCache.removeAll();
Complete post here : Power up $http with caching

Categories

Resources