I am trying to get dynamic data from the json according to $http results, but it doesn't work for me. I think that the problem is with the callback. I mean that is the code run to json results when my $http continue to run.
This is my javascript code:
var operation_types = operation_types = [
{nav_id: 1, nav_name: "Validation", nav_src: "validation", nav_href: "validation_list"},
{nav_id: 2, nav_name: "Guests", nav_src: "guests", nav_href: "guests_list"}
];
angular.module("mainApp", ["kendo.directives"])
.controller("HomepageCtrl", function ($scope,$http) {//Homepage
/*receive user properties*/
$http({
url: 'API/v1/User/GetUserInfo',
method: "GET",
headers: { 'Content-Type': 'application/json' }
}).success(function (data, status, headers, config) {
if (data.Code != 1) {
$scope.error = "Please enter valid username and password!";
} else {
console.log(data);
if(data.viewGuest==true&&data.viewValidation==true){
$scope.source =operation_types;
}else if(data.viewGuest==false){
source = operation_types[0];
}else if(data.viewValidation==false){
source = operation_types[1];
}
//window.location.href = "homepage.html";
}
}).error(function (data, status, headers, config) {
$scope.error = "There are problems with connection to server. Status:" + status + " Please, try to connect later.";
$scope.validationClass = "invalid";
});
$scope.source =operation_types;
})
This is the relevant snippet of my html code (with kendo ui):
<kendo-mobile-list-view k-data-source="source">
<div class="product" k-template>
<a href="\#{{dataItem.nav_href}}">
<img src="images/{{dataItem.nav_src}}.jpg" alt="{{dataItem.nav_name}} image" class="pullImage"/>
<h3>{{dataItem.nav_name}}</h3>
</a>
</div>
</kendo-mobile-list-view>
Does somebody know how to do it in angular?
Some general things to consider :
Your code is not using only vanilla angular , but also a 3rd party
library of client side controls (Telerik Kando)
Does the binding work if data is set to the sources json directly ?
Please see for example of kendo-mobile-list-view usage at http://demos.telerik.com/kendo-ui/mobile-listview/angular
Are you sure you the ajax request gets to the server ?
Are you sure the JSON returned is what you expect (use network
monitor in the dev tools in your browser of choice to find out , F12
usualy )?
Edit
Also
At
if(data.viewGuest==true&&data.viewValidation==true){
$scope.source =operation_types;
}else if(data.viewGuest==false){
source = operation_types[0];
}else if(data.viewValidation==false){
source = operation_types[1];
}
Sometimes you set the source on the $scope
$scope.source =operation_types;
and other you set a local variable named source.
source = operation_types[1];
Did you mean to set the
$scope.source
At the 2 last 'if' branches?
Another thing:
$http call is asynchrounus . So if you ment to assign initial value to
$scope.source
then it is better done before the ajax call , otherwise you risk a race condition.
Related
I am currently working on some project where I am writing UI code in angularjs.
I am stuck at framing the error handling.
The scenario is: I am writing some forms in angularJS. inside the controller I am making several $http calls which eventually call the servlets defined.
I need to notify the user about the success/failure of the servlets.
How can I achieve this?
Also, how can I handle the errors in this scenario?
For ex. when I submit the form below function gets executed:
`$scope.submitForm = function(form) {
console.log("--> Submitting form");
if(confirm("Are you sure to finish?")){
$http({
method : 'POST',
url : '/XMLParser',
dataType: 'JSON',
data : JSON.stringify($scope.form), //forms user object
headers : {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function(data) {
console.log(data);
if (data.errors) {
// Showing errors.
$scope.errorName = data.errors.name;
$scope.errorUserName = data.errors.username;
$scope.errorEmail = data.errors.email;
} else {
$scope.message = data.message;
}
alert("successful");
});
$scope.redirectToHome();
}
};`
The servlet /XMLParser will either successfully executed or may produce some errors. How can I handle those?
//Hope this could make sense
$http.get('your api url').then(success, failure);
function success(){
//your code when request respond success
};
function failure(){
//your code when request respond failure
};
Downloading a file used to work fine in my application until I upgraded Angular to the latest. Even now, the file is getting downloaded, but the issue is that it is getting corrupted. Upload file is working fine and if we check in the file server, the file will be intact. But upon download, I am getting corrupted file.
Html :
<td data-title="''">
<a tooltip="Download CV" ng-hide="!talent.resumePath" tooltip-trigger tooltip-animation="false" tooltip-placement="bottom" ng-click="downloadResume(talent.id)" data-placement="top" data-toggle="tooltip" data-original-title="resume">
<img src="../../img/DownloadIcon.png" /></a>
</td>
Controller :
downloadResume: function(employeeId) {
return apiServices.getFileFromTalentPool('/talentpool/resume?id=' + employeeId)
},
Where, getFileFromTalentPool is : https://hastebin.com/yivaterozi.js
Endpoint :
public FileResult GetResume(int id) {
var result = _services.GetResume(id);
if (result != null) {
HttpContext.Response.ContentType = result.ContentType;
HttpContext.Response.Headers["Access-Control-Expose-Headers"] = "FileName";
HttpContext.Response.Headers["FileName"] = result.FileDownloadName;
}
return result;
}
Usually I download Doc files. I tried with a notepad file to see if it's the same. Strangely, I noticed that I am able to open the notepad file, but its content is manipulated to something like [object Object]. But for Doc files, it just shows:
How can I fix this?
it looks like the code at https://hastebin.com/yivaterozi.js was updated from using deprecated $http.success() method to current $http.then(). Promise' success callback function (within then method) receives only one object argument: https://docs.angularjs.org/api/ng/service/$http. Deprecated 'success' method got more arguments (data, status, headers) and data already contained raw data. When using then(), data is located under data property of response, so try to change your $http call to:
$http({
method: 'GET',
cache: false,
url: fileurl,
responseType:'arraybuffer',
headers: {
'Authorization': "Bearer " + $rootScope.userInfo.access_token,
'Access-Control-Allow-Origin': '*'
}
}).then(function (data) {
var octetStreamMime = 'application/octet-stream';
var success = false;
// Get the headers
var headers = data.headers();
...
...
please note that headers are fetched correct here from the data object and not from the third argument (just add var, since we removed empty arguments).
Now in each place that you use data, change it to data.data, like:
// Try using msSaveBlob if supported
var blob = new Blob([data.data], { type: contentType });
or just change argument data to response and add var data = response.data; anf modify headers getter to headers = response.headers();:
$http({
method: 'GET',
cache: false,
url: fileurl,
responseType:'arraybuffer',
headers: {
'Authorization': "Bearer " + $rootScope.userInfo.access_token,
'Access-Control-Allow-Origin': '*'
}
}).then(function (response) {
var octetStreamMime = 'application/octet-stream';
var success = false;
// Get data
var data = response.data;
// Get the headers
var headers = response.headers();
...
...
I am trying to get a $http REST GET call working in my Appgyver project working but nothing I do seems to come right, always returns an error.
Please note the angular app will be running on mobile devices eventually and then connect to my remote web service.
I've double checked that my custom API is working and returning data correctly in a number of ways, namely:
hard coded cUrl request running from sh files in terminal - Returns data and correct 200 code
Tested the API end points in both POSTMAN and Firefox's SOA client.
Putting in my test end point of http://somesite.com/quote-and-buy-performance/druidapi/taxonomy_term returns data as below:
[{"tid":"1","vid":"2","name":"ACME Ltd.","description":"","format":"filtered_html","weight":"0","parent":"0","uri":"http://somesite.com/quote-and-buy-performance/druidapi/taxonomy_term/1"},{"tid":"2","vid":"2","name":"ABC Films LTD","description":"","format":"filtered_html","weight":"0","parent":"0","uri":"http://somesite.com/quote-and-buy-performance/druidapi/taxonomy_term/2"}]
Even a simple CSRF Token request gives me errors.
Could someone possibly point out where I am going wrong here, the Appgyver site is badly documented and I have tried the Angular RESTful sample which my code below is based upon from https://docs.angularjs.org/api/ng/service/$http and https://docs.angularjs.org/api/ng/service/$http#setting-http-headers
Please note the code below is basically Angular.js using Javascript syntax (as opposed to Coffeescript), logging output follows the code
angular
.module('main')
.controller('LoginController', function($scope, supersonic, $http) {
$scope.navbarTitle = "Settings";
$scope.stoken = "Response goes here";
$scope.processLogin = function(){
var csrfToken;
steroids.logger.log("START CALL: processLogin");
// $form_login_email_address = $scope.login_email;
// $form_login_password = $scope.login_password;
$local_get = "http://somesite.com/quote-and-buy-performance/services/session/token";
$hal_get_taxterm_index = "http://somesite.com/quote-and-buy-performance/druidapi/taxonomy_term";
// $http.defaults.headers.common.contentType('application/json');
var req = {
method: 'GET',
url: $hal_get_taxterm_index,
headers: {
'Content-Type': 'application/json'
}
}
$http(req)
.success(function(data, status, headers) {
steroids.logger.log("Inside http.get() success");
}).error(function(data, status, headers){
steroids.logger.log("Inside http.get() WITH ERROR");
steroids.logger.log('data: ' + data);
steroids.logger.log('status: ' + status);
}).then(function(data, status, headers){
steroids.logger.log("Inside http.get() then");
});
steroids.logger.log("END CALL: processLogin");
}
});
Logging output from calls to steroids.logger.log
View Time Level Message
main#login 16:01:55.219 info "Inside http.get() WITH ERROR"
main#login 16:01:55.219 info "data: null"
main#login 16:01:55.219 info "status: 0"
main#login 16:01:55.64 info "END CALL: processLogin"
main#login 16:01:55.64 info "START CALL: processLogin"
Here's what I would do:
Separate out your http call into a service. This is a pretty standard way to modularize your code in angular:
angular.module('main').factory("SomeService", function($http) {
return {
get: function() {
$http({
url: "http://somesite.com/quote-and-buy-performance/druidapi/taxonomy_term",
method: "GET",
headers: {
"Content-Type": "application/json"
}
}).success(function(data, status, headers, config) {
console.log("Success!");
console.log(data);
}).error(function(data, status, headers, config) {
console.log("Error!");
console.log(status);
console.log(data);
});
}
}
})
Then to use this in your controller, just include it in your controller declaration and call get like you would a normal method:
angular.module('main').controller('LoginController', function($scope, supersonic, SomeService) {
$scope.navbarTitle = "Settings";
$scope.stoken = "Response goes here";
$scope.processLogin = function(){
var csrfToken;
steroids.logger.log("START CALL: processLogin");
SomeService.get();
steroids.logger.log("END CALL: processLogin");
}
})
Do this and then comment back with your results and we can work from there.
If your angular's app is within a certain domain, then HTTP request must be made within the same domain.
In your case, you are trying a cross domain request (a request on another domain). You must then make a cross domain request.
You can see this question.
The author uses $http.jsonp() to send cross domain requests. There migth be another way to do it.
I encountered a bug in a square-connect API wrapper for node, and I made a fiddle to recreate the issue. I noticed my code wasn't working, in the sense that angular {{}} stuff isn't showing up. What's wrong with it?
the only thing I'm trying to do is have the raw JSON object (preferably {{res}}, but it doesn't matter really) shown below the create button. I am just trying to demonstrate to the author of a library that my object and data is valid, and that a bug is in his library, not my implementation.
var httpRequest = $http({
method: 'POST',
url: '/echo/json/',
data: item
}).success(function(data, status) {
$scope.res = data;
}).failure(function(data, status){
$scope.res = data+status;
});
data is not being returned from jsfiddle's ECHO.
http://jsfiddle.net/efjytg6r/2/
You were close, but since you're saving your $http in a variable, you access the methods within it using that variable. (ie: httpRequest.success / etc)
Also it's .error() not .failure()
var httpRequest = $http({
method: 'POST',
url: '/echo/json/',
data: item
});
httpRequest.success(function(data, status) {
$scope.res = data;
});
httpRequest.error(function(data, status){
$scope.res = data+status;
});
jsFiddle is finicy with it's echo AJAX examples. You need to format what you send to them correctly with json, have it stringified as well as use jQuery's $.param (since angular doesn't do POST like you're used to with jQuery).
I included jQuery to the fiddle below.
I formatted the data being sent differently
I moved your {{ res }} inside of the controller area (you had it outside, which means it won't compute)
I added | json filter to {{ res | json }}
Updated jsFiddle
// the wacky format you need if you want to do fake $http to jsFiddle
// case in point, if you're trying to DEMO this, I wouldn't even bother, since it won't look like this when you actually use this within your application
var data = $.param({
json: JSON.stringify({
item
})
});
$http.post("/echo/json/", data)
.success(function(data, status) {
$scope.res = data;
}).error(function (status) {
});
Here is an example using $httpParamSerializer and a delay.
angular.module('myApp',[]);
angular.module('myApp').controller('myVm',
function($scope,$http,$httpParamSerializer) {
var vm = $scope;
var xitem = {a:"1",b:"2"};
var data = $httpParamSerializer({
json: xitem,
delay: 6
});
console.log("Posting xitem");
vm.p = $http.post('/echo/json/',data);
vm.p.then (function(response) {
console.log(response);
console.log(response.data)
})
});
So I have a service like that:
.service("checkSystemStatus", ["$http", "statusUrl", function($http, statusUrl){
return $http({method: "GET", url: statusUrl, cache: false});
}])
With this markup:
<li ng-mouseenter="checkStatus()">
<i class="fa fa-info-circle"></i>
<div class="info-container">
<h4>System Info</h4>
<table class="system-info">
<tr ng-repeat="(key, value) in systemInfo">
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
</table>
</div>
</li>
and this function:
$scope.checkStatus = function(){
$scope.systemInfo = {};
checkSystemStatus.then(function(success){
$scope.systemInfo.running = success.data.jobs_running;
$scope.systemInfo.queued = success.data.jobs_queued;
$scope.systemInfo.cached = success.data.jobs_cached;
$scope.systemInfo.active_threads = success.data.threads_active;
$scope.systemInfo.server_address = success.data.server_address;
$scope.systemInfo.server_port = success.data.server_port;
console.log($scope.systemInfo);
})
}
The issue is I always get the same values for systemInfo, anytime I hover the info icon, I can't see any XHR requrest in the console except for the first one, that happens on loading the page and NOT when I hover the mouse on the tag.
The only way to solve this so far has been adding a parameter at the end of the url like
?time=unixtime to get a new url each time, but what about a cleaner solution without trailing params? Is it possible?
Well, it not only depends on the "AngularJS"-Cache but also on the Browser and Server cache settings. Check what kind of Cache-Headers the server in his responses sends to the Client. Adding a "timestamp" parameter to the REST-URL is one trick to avoid browser based caching - yes.
But in general: That's the way a client-server communication is intended to be. I would suspect that the Server sends some Vary, ETag, Cache-Expire etc. headers which will match.
Try to add these http headers into the server's response:
Cache-Control:no-cache, no-store, must-revalidate
Expires:-1
Pragma:no-cache
Try like this
.service("checkSystemStatus", ["$http", "statusUrl", '$q', function($http, statusUrl, $q){
this.GetData = function(){
$http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
return $http({
method: "GET",
url: statusUrl,
cache: false //no need to use this, caching is false by default
}).
then( function(response){
if (response.data) {
return response.data;
}
else
return $q.reject('Request failed');
});
}
}]);
Controller part
$scope.checkStatus = function(){
$scope.systemInfo = {};
checkSystemStatus.GetData().then(function(data){
$scope.systemInfo.running = data.jobs_running;
$scope.systemInfo.queued = data.jobs_queued;
$scope.systemInfo.cached = data.jobs_cached;
$scope.systemInfo.active_threads = data.threads_active;
$scope.systemInfo.server_address = data.server_address;
$scope.systemInfo.server_port = data.server_port;
console.log($scope.systemInfo);
})
}
As other answers tell you: the browser may choose to cache the response if the appropriate response headers from the server is not set. Set the response headers in MajoBs answer.
If you are unable to update the response headers from the server you could make sure that the url is unique for every request. You can do this by adding a timestamp to the url:
.service("checkSystemStatus", ["$http", "statusUrl", function($http, statusUrl){
statusUrl = statusUrl + '?' + Date.now();
return $http({method: "GET", url: statusUrl, cache: false});
}])