i now trying to migrate my legace app to Angular and now stuck with following issue.
I have this simple form:
<form name="loginForm" ng-controller="LoginCtrl" ng-submit="doLogin()">
<input type="text" name="login" ng-model="login.login" />
<span class="errors" ng-show="loginForm.login.$error.required">Required</span>
<span class="errors" ng-show="loginForm.login.$error.bad_login">Login or pass incorrect</span>
<input type="password" ng-model="login.pass"/>
</form>
Server returns error as this type of JSON: { login: 'bad_login', pass: 'incorrect' }
And in controller:
function LoginCtrl($scope, $http) {
$scope.doLogin = function() {
var model = $scope.login;
var req = { "login": model.login, "pass": model.pass };
$http({ method: "POST", url: "/login", data: req }).success(function (resp) {
if(resp.status != "ok") {
angular.forEach(resp, function (value, key) {
// ex: model['login'].$setValidity('bad_login', false);
model[key].$setValidity(value, false);
});
}
});
};
}
I try to mark each field in loop, not to hardcode every field by hand. but this approach not working. I get this error: TypeError: Cannot call method '$setValidity' of undefined, even when field is left empty i have another error: TypeError: Cannot read property 'login' of undefined
So i think i need to get instance of model for every field in form, any ideas ?
The reason it's coming back undefined is because unless you actually specify something for $scope.login.login or $scope.login.pass to begin with, they aren't set. If you put a space and delete it, you'll see they are set as blank. What you're going to want to do is at the beginning of your controller define the login on the scope like so:
function LoginCtrl($scope, $http) {
$scope.login = {
login: "",
pass: ""
};
$scope.doLogin = function() {
var req = { "login": $scope.login.login, "pass": $scope.login.pass };
$http({ method: "POST", url: "/login", data: req }).success(function (resp) {
if(resp.status != "ok") {
angular.forEach(resp, function (value, key) {
// ex: model['login'].$setValidity('bad_login', false);
$scope.login[key].$setValidity(value, false);
});
}
});
};
}
Related
HTML
<form ng-controller="updatecontroller" ng-submit="updateUser()"><label class="control-label">First Name</label>
<input type="text" ng-model="user.userFirstName">
<label class="control-label">Last Name</label>
<input type="text" ng-model="user.userLastName" ><button type="submit" ng-click="updateUser()">Update</button>
</form>
JS
app.controller('updatecontroller', function ($scope, $http, $cookieStore) {
$http.get('http://localhost:8080/myapp/user/'.concat($scope.getUserId) + '?access_token=' + $cookieStore.get("access_token")).
then(function (response) {
$scope.user = response.data;
});$scope.user = {"id": "","userFirstName": "","userLastName": ""}
$scope.updateUser = function () {
var url = "http://localhost:8080/myapp/user/".concat($scope.getUserId) + "?access_token=" + $cookieStore.get("access_token");
var method = "PUT";
$http({
method: method,
url: url,
data: angular.toJson($scope.user),
headers: {
'Content-Type': 'application/json'
}
})
};});
values will appear in text field. i have to update. the values are getting updated in database. but what i want is.. the updated values should not clear after submit the form.
Thanks!
You can empty the input filed after get the response from HTTP request
$scope.updateUser = function () {
$http({
method: 'POST',
url: 'myUri',
data: 'your data'
headers:'header'
}).then(
function(res) {
$scope.user = {"id": "","userFirstName": "","userLastName": ""} //clear the input field here
},
function(err) {
}
);
}
Place your Submit Button inside the Form Element then try it it will clear the input after the submission.
your updateUser() method seems to be the problem. It's probably clearing user.userFirstName & user.userLastName (or the whole user)
please show us what updateUser() is doing to be sure
I'm new to AngularJS and
I needed to know if we can make a jQuery like Ajax call in Angular and wanted to know it's complete syntax,
if anyone could help me making the whole code syntax.
Example in jQuery I could do something like -
$.ajax(
{
url: 'someURL',
type: 'POST',
async: false,
data:
{
something: something,
somethingelse: somethingelse
},
beforeSend: function()
{
$('#someID').addClass('spinner');
},
success: function(response)
{
$('#someID').removeClass('spinner');
console.log(response);
},
complete: function(response)
{
$('#someID').removeClass('spinner');
console.log(response);
},
error: function (errorResp)
{
console.log(errorResp);
}
});
Now here's what I found out on making http call in Angular,
Need help in building the complete syntax, with all possible options -
var req = {
method: 'POST',
url: 'someURL',
headers: {
'Content-Type': undefined
},
data: {
//goes in the Payload, if I'm not wrong
something: 'something'
},
params:{
//goes as Query Params
something: 'something',
somethingElse: 'somethingElse'
}
}
$http(req)
.then(function()
{
//success function
},
function()
{
//Error function
});
now what if I want to attach a spinner on some id in the BeforeSend function like in jQuery and remove the spinner in success,
What is the Angular's way as a like to like for BeforeSend or making the http call async?
Angular even let you control this better :). Two ways can be chosen here:
1. Wrapping $http
You can write for each request with by using a wrapper of $http which will add some methods before and after you made request
app.factory('httpService',function($http){
function beginRequest() {};
function afterRequest() {};
return {
makeRequest: function(requestConfig){
beginRequest();
return $http(requestConfig).then(function(result){
afterRequest(result);
});
}
}
})
Then each time you can call this function to make a request. This is not new.
2. Using interceptor
Angular has a better way to handle for all request. It use a new concept named 'interceptor'. You write your interceptor as a normal service and push one or many interceptors into $http service and depend on type of interceptor, it will be called each time your request happen. Look at this picture to think about interceptor:
Some common task for interceptor can be: Add/remove a loading icon, add some more decorator to your http config such as token key, validate request, validate responded data, recover some request...
Here is example of a interceptor that add a token key into headers of a request
app.service('APIInterceptor', function($rootScope, UserService) {
var service = this;
service.request = function(config) {
var currentUser = UserService.getCurrentUser(),
access_token = currentUser ? currentUser.access_token : null;
if (access_token) {
config.headers.authorization = access_token;
}
return config;
};
service.responseError = function(response) {
return response;
};
})
Then add interceptor to your $http:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('APIInterceptor');
}]);
Now all request will be added a token key to header. cool right?
See here for more information:
there is eveyrthing here to help with your question :https://docs.angularjs.org/api/ng/service/$q http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/
$http functions are async by default.
And regarding the beforesend function, you could wrap the http call in a function and add the spinner just before making the call and remove it in the success call back. Something like this,
var makeHttpRequest = function(){
$('#someID').addClass('spinner');
$http(req).then(function(){
$('#someID').removeClass('spinner');
//rest processing for success callback
},function(){
$('#someID').removeClass('spinner');
//Error callback
});
}
The way I have implemented complex get and post in my angular application is as below:
Create a CRUDService as below:
yourApp.service('CRUDService', function ($q, $http) {
this.post = function (value, uri) {
var request = $http({
method: "post",
url: uri,
data: value
});
return request;
}
this.get = function (uri) {
var request = $http({
method: "get",
url: uri
});
return request;
}
});
As you can see this service simply returns a get/post object. Somewhere in my controller I use this service as below:
$('#exampleButton').button("loading"); //set the element in loading/spinning state here
var getObj = CRUDService.get("/api/get/something");
getObj.then(function(data){
//do something
$('#exampleButton').button("reset"); //reset element here
}, function(err){
//handle error
$('#exampleButton').button("loading"); //reset element here
});
$('#exampleButton').button("loading"); //set the element in loading/spinning state here
var postObj = CRUDService.post(postData,"/api/get/something");
postObj.then(function(data){
//do something
$('#exampleButton').button("reset"); //reset element here
}, function(err){
//handle error
$('#exampleButton').button("loading"); //reset element here
});
I hope this helps :)
The http call is async - it returns a promise that you can then handle with the try() and catch() methods. You can simply wrap your calls i.e.
function makeRequest() {
$scope.showSpinner = true;
$http
.get('http://www.example.com')
.then(function (response) {
$scope.showSpinner = false;
})
.catch(function (err) {
$scope.showSpinner = false;
});
}
If you would however like you use familiar syntax akin to jQuery then you can push your own custom interceptors. This will allow you intercept the requests and response and do whatever you want. In the below example we call functions if they are defined.
angular
.module('app', [])
.config(appConfig)
.factory('HttpInterceptors', httpInterceptors)
.controller('MyController', myController);
// app config
appConfig.$inject = ['$httpProvider'];
function appConfig($httpProvider) {
// add out interceptors to the http provider
$httpProvider.interceptors.push('HttpInterceptors');
}
// http interceptor definition
function httpInterceptors() {
return {
request: function(request) {
if (angular.isFunction(request.beforeSend)) {
request.beforeSend();
}
return request;
},
response: function(response) {
if (angular.isFunction(response.config.onComplete)) {
response.config.onComplete();
}
return response;
}
}
}
// controlller
myController.$inject = ['$scope', '$http', '$timeout'];
function myController($scope, $http, $timeout) {
$scope.showSpinner = false;
$http({
method: 'GET',
url: 'https://raw.githubusercontent.com/dart-lang/test/master/LICENSE',
beforeSend: function() {
$scope.showSpinner = true;
},
onComplete: function() {
$timeout(function() {
console.log('done');
$scope.showSpinner = false;
}, 1000);
}})
.then(function(response) {
console.log('success');
})
.catch(function(err) {
console.error('fail');
});
}
.spinner {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<div ng-app='app' ng-controller='MyController'>
<div ng-class='{spinner: showSpinner}'>
Hello World!
</div>
</div>
I try to pass my form parameters to java rest backend but i cant.
controller
$scope.addNewThing = function () {
Myservice.addNew($scope.name);
};
service
addNew: function (name) {
var Foo = $resource($rootScope.baseUrl + '/path/addNew', {}, {
save: {method: 'POST', params: {}}
});
var results = Foo.save({name: name}, function(data) {
results = data;
});
return results;
}
//also tried this version of code
addNew: function(name) {
return $resource($rootScope.baseUrl + '/path/addNew', {}, {
save: {method: 'POST', params: {name: 'test'}}
});
}
rest backend function
#POST
#Produces("application/json")
#Path("/addNew")
public Response addNew(#FormParam("name") String name) {
try {
//when i check name here it is always null
...
}
}
I can't pass the html form parameter to java rest backend via angular. Also tried to change #FormParam to #QueryParam but it didn't work.
Did you set the default content-type on $http POST requests?
app.config(function($httpProvider) {
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.post["Content-Type"] = "application/json; charset=utf-8";
});
I don'n know how to receive params value in java but I can show how to pass params from angular service. when you will want to pass params then you should use :paramsName in your URL path.
addNew: function(name) {
var addNewItem = $resource($rootScope.baseUrl + '/path/addNew/:name', {name: '#name'}, {
'post': {method: 'GET'}
});
return addNewItem.post({name: name});
}
or if you don't use /:name in your url you should pass in your header
addNew: function(name) {
var addNewItem = $resource($rootScope.baseUrl + '/path/addNew/:name', {}, {
'post': {method: 'GET', headers: { 'name': name }}
});
return addNewItem.post({name: name});
}
NB: your Content-Type should be application/json
You can try this:
CONTROLLER
$scope.addNewThing = function () {
yourService.addNew($scope.name);
};
SERVICE
angular.module('MyApp')
.service('yourService',['$http', function ($http) {
this.addNew = function (data) {
$http({
url: 'YourURL',
method: 'POST',
data: data, // your $scope.name
headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}
})
.success(function (response) {
console.log('good');
})
.error(function (response) {
console.log('error');
});
};
}]);
JAVA REST API
#POST
#Path("/addNew")
#Consumes("*/*")
public Response addNew(String name) {
// use here your String name
}
Using jQuery params solved my problem
Here is the correct way:
Myservice.addNew().save($.param({
name:$scope.name
}),function(data){
console.log(data);
},function(err){
console.log(err);
});
I can pass the parameters like this with $resource service.
I am trying to do a login for my app, using a rest api I designed. If I force the complete URL with the user and the pass It works alright:
http://www.myexample.com/ACTION/USER/PASSWORD/
But I need to take the data from the input fields of my form. This is code of the function in my controller:
$scope.authenticar = function(selectedUs, selectedPw){
$scope.remoteData = null;
//alert(selectedUs);
dataService.getData(function(data) {
$scope.resultAPI = data;
$scope.username=$scope.resultAPI.username;
$scope.id_user=$scope.resultAPI.id_user;
$scope.isauthenticated=$scope.resultAPI.isauthenticated;
$scope.user_role=$scope.resultAPI.user_role;
$scope.complete_name=$scope.resultAPI.complete_name;
});
}
And this is the service code:
.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function(callback) {
var myparams = {a: '', u: '', p: ''};
myparams.a = 'ZW50cmFy';
myparams.u = 'anRk';
myparams.p = '899960d8dd39b29e790845912cb35d96';
$http({
method: 'GET',
url: 'http://www.adagal.net/api_adagal/api.php',
withCredentials: false,
params: myparams,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).success(function(data, status, header, config){
// With the data succesfully returned, call our callback
callback(data);
}).error(function(){
$scope.remoteData = null;
return "Connection Error";
});
}
});
I tried to pass all the ways, how can I get the URL this way?
Not entirely sure what you are trying to do here, you want to pass username and password by url? or post/get data?
Either way you'll need to pass the username and password into the service. You can do that by passing it in the service function.
this.getData = function(username, password, callback) {
...
})...
}
On the calling side:
dataService.getData($scope.username, $scope.password, function(){...});
If I understood your question correctly, you should change your service like this:
.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function(URL, callback) {
var myparams = {a: '', u: '', p: ''};
myparams.a = 'ZW50cmFy';
myparams.u = 'anRk';
myparams.p = '899960d8dd39b29e790845912cb35d96';
$http({
method: 'GET',
url: URL,
withCredentials: false,
params: myparams,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).success(function(data, status, header, config){
// With the data succesfully returned, call our callback
callback(data);
}).error(function(){
$scope.remoteData = null;
return "Connection Error";
});
}
});
And then call it like this:
var url = "http://wwwmyexample.com/ACTION/" + $scope.selectedUs + "/" + $scope.selectedPw + "/"
dataService.getData(url, function(data) {
$scope.resultAPI = data;
$scope.username=$scope.resultAPI.username;
$scope.id_user=$scope.resultAPI.id_user;
$scope.isauthenticated=$scope.resultAPI.isauthenticated;
$scope.user_role=$scope.resultAPI.user_role;
$scope.complete_name=$scope.resultAPI.complete_name;
});
And in HTML you should have smth like this:
<input ng-model="selectedUs" />
<input ng-model="selectedPw" />
Thank you all for the answers. I found my error:
dataService.getData(function(u, p, data) {
And here was my error
dataService.getData(u, p, function(data) {
I was putting u and p beside data, unforgivable error. Thank you all for the help.
I have a function which does a http POST request. The code is specified below. This works fine.
$http({
url: user.update_path,
method: "POST",
data: {user_id: user.id, draft: true}
});
I have another function for http GET and I want to send data to that request. But I don't have that option in get.
$http({
url: user.details_path,
method: "GET",
data: {user_id: user.id}
});
The syntax for http.get is
get(url, config)
An HTTP GET request can't contain data to be posted to the server. However, you can add a query string to the request.
angular.http provides an option for it called params.
$http({
url: user.details_path,
method: "GET",
params: {user_id: user.id}
});
See: http://docs.angularjs.org/api/ng.$http#get and https://docs.angularjs.org/api/ng/service/$http#usage (shows the params param)
You can pass params directly to $http.get() The following works fine
$http.get(user.details_path, {
params: { user_id: user.id }
});
Starting from AngularJS v1.4.8, you can use
get(url, config) as follows:
var data = {
user_id:user.id
};
var config = {
params: data,
headers : {'Accept' : 'application/json'}
};
$http.get(user.details_path, config).then(function(response) {
// process response here..
}, function(response) {
});
Solution for those who are interested in sending params and headers in GET request
$http.get('https://www.your-website.com/api/users.json', {
params: {page: 1, limit: 100, sort: 'name', direction: 'desc'},
headers: {'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
}
)
.then(function(response) {
// Request completed successfully
}, function(x) {
// Request error
});
Complete service example will look like this
var mainApp = angular.module("mainApp", []);
mainApp.service('UserService', function($http, $q){
this.getUsers = function(page = 1, limit = 100, sort = 'id', direction = 'desc') {
var dfrd = $q.defer();
$http.get('https://www.your-website.com/api/users.json',
{
params:{page: page, limit: limit, sort: sort, direction: direction},
headers: {Authorization: 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
}
)
.then(function(response) {
if ( response.data.success == true ) {
} else {
}
}, function(x) {
dfrd.reject(true);
});
return dfrd.promise;
}
});
You can even simply add the parameters to the end of the url:
$http.get('path/to/script.php?param=hello').success(function(data) {
alert(data);
});
Paired with script.php:
<? var_dump($_GET); ?>
Resulting in the following javascript alert:
array(1) {
["param"]=>
string(4) "hello"
}
Here's a complete example of an HTTP GET request with parameters using angular.js in ASP.NET MVC:
CONTROLLER:
public class AngularController : Controller
{
public JsonResult GetFullName(string name, string surname)
{
System.Diagnostics.Debugger.Break();
return Json(new { fullName = String.Format("{0} {1}",name,surname) }, JsonRequestBehavior.AllowGet);
}
}
VIEW:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script type="text/javascript">
var myApp = angular.module("app", []);
myApp.controller('controller', function ($scope, $http) {
$scope.GetFullName = function (employee) {
//The url is as follows - ControllerName/ActionName?name=nameValue&surname=surnameValue
$http.get("/Angular/GetFullName?name=" + $scope.name + "&surname=" + $scope.surname).
success(function (data, status, headers, config) {
alert('Your full name is - ' + data.fullName);
}).
error(function (data, status, headers, config) {
alert("An error occurred during the AJAX request");
});
}
});
</script>
<div ng-app="app" ng-controller="controller">
<input type="text" ng-model="name" />
<input type="text" ng-model="surname" />
<input type="button" ng-click="GetFullName()" value="Get Full Name" />
</div>
For sending get request with parameter i use
$http.get('urlPartOne\\'+parameter+'\\urlPartTwo')
By this you can use your own url string