$http only calls error when making simple ajax request? - angularjs

I feel like I'm missing something small. Here's my index.html:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="ImageViewerApp">
<head>
<title></title>
<script type="text/javascript" src="/scripts/angular.js"></script>
<script type="text/javascript" src="/scripts/Controller.js"></script>
</head>
<body ng-controller="ImageViewerCtrl">
<p>{{Value}}</p>
</body>
</html>
My Controller.js:
var ImageViewer = angular.module('ImageViewerApp', []);
ImageViewer.controller('ImageViewerCtrl', [ '$scope', '$http', ImageViewerCtrl ]);
function ImageViewerCtrl($scope, $http) {
$scope.Value = 'Test';
$http.get('data/job.json').success(function (data) {
$scope.Value = data.Test;
}).error(function (data, status, headers, config) {
data = data;
});
}
My job.json:
{
Test: 'Hello, World!'
}
And my Web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json"/>
</staticContent>
</system.webServer>
</configuration>
I'm working in VS 2012 and I've made a simple blank website. Debugging the site runs it in IIS Express and IE 10. Other browsers might work, but the eventual project this will be used in will be an internal web app running on only IE 10.
I'm trying to do something similar to how the Angular Tutorial makes an AJAX request to a .json file in order to simulate a web request. I was first running into some issues about not having a handler defined for the .json file type, but I added a mimeMap to the Web.config and now fiddler reports that the request for /data/job.json is coming back as either a 200 or a 304 (Not Modified) but the error part of the promise is the only one that ever gets called.
data = data; is there simply so I can place a breakpoint in Visual Studio. data, status, and headers are all undefined and config doesn't seem to say anything useful, but here's the result of JSON.stringify(config) if it helps:
{"method":"GET","transformRequest":[null],"transformResponse":[null],"url":"/data/job.json","headers":{"Accept":"application/json, text/plain, */*"}}
What am I doing wrong that sets off error instead of calling success?
EDIT: Wandering through the call stack and looking at the state inside angular.js, I've found that somewhere in the bowels of angular it does have the response I expect for requesting job.json, but later in the stack there's an error (that isn't successfully passed to my error callback) that simply says Invalid Character. I don't know what character it could be hanging up on. This hasn't helped me figure out what's going wrong, but maybe it'll help get an answer here.

{Test: "value"}
It isn't valid JSON when returning it in it's RAW form. You will need to add the appropriate " (Quotes) around the key.
{"Test": "value"}

Related

Fetching data from query string REST API in angularjs [duplicate]

I am very new to angularJS. I am searching for accessing services from RESTful API, but I didn't get any idea. How can I do that?
Option 1: $http service
AngularJS provides the $http service that does exactly what you want: Sending AJAX requests to web services and receiving data from them, using JSON (which is perfectly for talking to REST services).
To give an example (taken from the AngularJS documentation and slightly adapted):
$http({ method: 'GET', url: '/foo' }).
success(function (data, status, headers, config) {
// ...
}).
error(function (data, status, headers, config) {
// ...
});
Option 2: $resource service
Please note that there is also another service in AngularJS, the $resource service which provides access to REST services in a more high-level fashion (example again taken from AngularJS documentation):
var Users = $resource('/user/:userId', { userId: '#id' });
var user = Users.get({ userId: 123 }, function () {
user.abc = true;
user.$save();
});
Option 3: Restangular
Moreover, there are also third-party solutions, such as Restangular. See its documentation on how to use it. Basically, it's way more declarative and abstracts more of the details away from you.
The $http service can be used for general purpose AJAX. If you have a proper RESTful API, you should take a look at ngResource.
You might also take a look at Restangular, which is a third party library to handle REST APIs easy.
Welcome to the wonderful world of Angular !!
I am very new to angularJS. I am searching for accessing services from RESTful API but I didn't get any idea. please help me to do that. Thank you
There are two (very big) hurdles to writing your first Angular scripts, if you're currently using 'GET' services.
First, your services must implement the "Access-Control-Allow-Origin" property, otherwise the services will work a treat when called from, say, a web browser, but fail miserably when called from Angular.
So, you'll need to add a few lines to your web.config file:
<configuration>
...
<system.webServer>
<httpErrors errorMode="Detailed"/>
<validation validateIntegratedModeConfiguration="false"/>
<!-- We need the following 6 lines, to let AngularJS call our REST web services -->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="Content-Type"/>
</customHeaders>
</httpProtocol>
</system.webServer>
...
</configuration>
Next, you need to add a little bit of code to your HTML file, to force Angular to call 'GET' web services:
// Make sure AngularJS calls our WCF Service as a "GET", rather than as an "OPTION"
var myApp = angular.module('myApp', []);
myApp.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);
Once you have these fixes in place, actually calling a RESTful API is really straightforward.
function YourAngularController($scope, $http)
{
$http.get('http://www.iNorthwind.com/Service1.svc/getAllCustomers')
.success(function (data) {
//
// Do something with the data !
//
});
}
You can find a really clear walkthrough of these steps on this webpage:
Using Angular, with JSON data
Good luck !
Mike
Just to expand on $http (shortcut methods) here: http://docs.angularjs.org/api/ng.$http
//Snippet from the page
$http.get('/someUrl').success(successCallback);
$http.post('/someUrl', data).success(successCallback);
//available shortcut methods
$http.get
$http.head
$http.post
$http.put
$http.delete
$http.jsonp
For instance your json looks like this :
{"id":1,"content":"Hello, World!"}
You can access this thru angularjs like so:
angular.module('app', [])
.controller('myApp', function($scope, $http) {
$http.get('http://yourapp/api').
then(function(response) {
$scope.datafromapi = response.data;
});
});
Then on your html you would do it like this:
<!doctype html>
<html ng-app="myApp">
<head>
<title>Hello AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script src="hello.js"></script>
</head>
<body>
<div ng-controller="myApp">
<p>The ID is {{datafromapi.id}}</p>
<p>The content is {{datafromapi.content}}</p>
</div>
</body>
</html>
This calls the CDN for angularjs in case you don't want to download them.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script src="hello.js"></script>
Hope this helps.

AngularJS routing paths to Express server

I am a beginner to AngularJS, Node and Express.
I can't get even the most basic routing to work with $http.get or $http.post.
Every example I have found online leaves out the relationship between the filenames, the Angular controller path, and the route path in the server. They just show the code without showing the paths and filenames.
Here is my html file: "/programs/static/example.html":
<!DOCTYPE html>
<html ng-app="exampleApp">
<head>
</head>
<body>
<div ng-controller="exampleController">
<input type="submit" value="Click me" ng-click="request()">
</div>
<script src="http://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="/js/example-controller.js"></script>
</body>
</html>
Here is my Angular controller: "/programs/static/js/example-controller.js"
var exampleApp = angular.module('exampleApp', []);
exampleApp.controller('exampleController', function($scope) {
$scope.request = function() {
data="test";
$http.post("/" , data);
};
});
And here is my NodeJS server: "/programs/node-server.js"
var express = require("express");
var app = express();
app.use('/', express.static('./static'));
app.post('/example.html/', function(req, res){
console.log("request received.");
});
app.listen(80);
The problem is that the console of my server doesn't display "request received." This is an example app I built just to post this to Stack Overflow. In my real app I have tried as many different routes as possible. I can get app.get() in my node server to work using simple URLs (not $http methods). But it is obvious from my testing that my Angular controller isn't sending any requests, or else the server isn't receiving them.
Your POST endpoint should not have a file extension in it's name. Any posts to "example.html" will try to return an actual html file named example.html if you have any such file name in your \static folder. Your API endpoints should have clear unique names, with no file extension:
app.post('/test', function(req, res){
console.log("request received.");
});
When using $http.post and passing "/" as the parameter, the actual URL that is posted to will be relative to your current URL. You should always use an absolute URL when posting to a server (unless you know what you are doing). You should also implement the .then and .catch methods. These will help you debug the problem:
$http.post("http://localhost:8080/test", data).then(function(response) {
console.log(response); //this will log a success
}).catch(function(error) {
console.log(error); //this will log the error
});
You are also forgot to inject the $http provider in your controller:
exampleApp.controller('exampleController', function($scope, $http) {
...
});

AngularJS getting strange response from using get on json rest service with no data

This has been frustrating me a bit. I have a restful services giving JSON data running on the link: http://localhost:51133/API/SalesSystem/
So its running locally on my computer. I can get the data from this service with no problem using my WPF based interface.
Another service I am testing with is this one: http://rest-service.guides.spring.io/greeting
But from my own service something seems to go wrong somehow and I cannot figure out what goes wrong. The spring service gives me a response using a response function, but my service gives a response using a success function function. Very confusing.
Response seems to be:
{"data":null,"status":-1,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"http://localhost:51133/API/SalesSystem/","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":"","xhrStatus":"error"}
I looked it up and it seemed I might be needed to enable Cors, but I am not entirely sure how. I installed it from NuGet, the service is running with Visual Studio, and I added config.EnableCors(); to my WebApiConfig.
My JS script:
angular.module('demo', [])
.controller('Hello', function ($scope, $http) {
$http.get('http://localhost:51133/API/SalesSystem/')
//http://rest-service.guides.spring.io/greeting
//http://localhost:51133/API/SalesSystem/
.then(function (response) {
$scope.hello = 'hello';
$scope.district = response.data;
console.debug(response.data);
console.log(response.data)
}, function success(response) {
$scope.hello = 'hello2';
$scope.district = response;
$scope.rep = response.data;
console.debug(response.data[0]);
$scope.district = response.data[0];
console.log(success.data)
}, function error(response) {
$scope.hello = 'hello3';
$scope.district = error.data;
console.log(error.data)
});
});
My html:
<!doctype html>
<html ng-app="demo">
<head>
<title>Hello AngularJS</title>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/hello.js"></script>
</head>
<body>
<div ng-controller="Hello">
<li>Id: <button>{{hello}}</button></li>
<li>Area: {{district}}</li>
<ul ng-repeat="obj in hello">
<li>Area: {{obj.area}}</li>
</ul>
<p>The ID is {{rep.Id}}</p>
<p>The content is {{hello.Area}}</p>
</div>
</body>
</html>
I am getting it all to work with my WPF based frontend using this service, not sure why it wont work with AngularJS.
The CORS issue has nothing to do with angular. It has got more to do with the browser .
In layman terms , the cors situation is where the browser does not allow responses of other origins than the url to be processed unless the response has a certain set of headers .Of course, it is a bit more complicated than that .Since the response does not have those headers you are getting the CORS issue
For a quick fix you can disable CORS in your browser .
for example :- if you are using chrome you can run it --disable-web-security flag

$http in angularjs not working

I have a piece of Code in angularjs. If I hard code the value of http response it is displaying the response when I use the http method in angularjs it is not displaying. But I am getting response to that link locally. I dont know where I am wrong. Here is the code
<!DOCTYPE html>
<html>
<head>
<script script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
angular.module('myApp', [])
.controller('MyCtrl', function($scope,$http){
$scope.test = [
{
"done": 2,
"total": 7
}
];
});
</script>
</head>
<body ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat="t in test">
<span>{{t.done}}</span>
<span>{{t.total}}</span>
</div>
</body>
</html>
In Script again if i add the below code,its not displaying the values
<script>
angular.module('myApp', [])
.controller('MyCtrl', function($scope,$http){
$http.get("http://localhost:8080/reports/webapi/hello/myresource2").then(function (response) {
$scope.test = response;
});
});
</script>
Try disabling web security of google chrome if you are running google chrome and run your application it will work normally.
Your problem is not with $http rather with CORS.
I've ran into this issue when I was learning angularJS.
Since AngularJS or new frameworks using AJAX extensively there is a small issue called CORS(Cross origin resource sharing) which means we can access a resource from the same domain due to security concerns.
Please refer Understanding CORS.
Web applications are served by servers however you've tried to open your html directly in browser which means you are trying to access a http resource from file protocol which is not allowed as per CORS.
You've two options to use.
Disable web security in google chrome
Run your application in a static server.
Your actual data resides in response.data. So update your scope variable accordingly,
Your controller code,
angular.module('myApp', [])
.controller('MyCtrl', function($scope, $http) {
$http.get("http://localhost:8080/reports/webapi/hello/myresource2")
.then(function (response) {
$scope.test = response.data;
});
});
Hope this solves the issue.
try to add another function for the catching of error response
$http.get("http://localhost:8080/reports/webapi/hello/myresource2").then(function (response) {
$scope.test = response;
}, function(response){
console.log(response)
});
I also went to the similar problem and solved by adding the following HTTP headers at the response of the receiving end.
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin:
You may prefer not to use the * at the end, but only the domainname of the host sending the data. Like *.example.com
But this is only feasible when you have access to the configuration of the server.
You need to add these headers in the server, not in AngularJS
Since you are sending json data through your api .You have to do like this.
<script>
angular.module('myApp', [])
.controller('MyCtrl', function($scope,$http){
$http.get("http://localhost:8080/reports/webapi/hello/myresource2").then(function (response) {
$scope.test = response.data;
});
});
</script>

No 'Access-Control-Allow-Origin' error from local domain to public API

I'm trying to create an app that will retrieve the stock name, asking and buy price from Yahoo Finance API, using Restangular. I'm having a problem with accessing a public API in the local application I'm creating when I do a GET request. This is the URL with parameters that I'm sending:
http://finance.yahoo.com/d/quotes.csv?s=MSFT+GE&f=nab
Using Postman, this get request returns an array which contains the stock name, asking price and buy price of the stock. Doing the request in postman returns the desired information without any errors.
When I do this request in my local, I get the following error:
XMLHttpRequest cannot load http://finance.yahoo.com/d/quotes.csv?s=MSFT+GE&f=nab. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
The HTML code is as follows:
<html ng-app="app">
<head>
<title>Restangular</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="//code.angularjs.org/1.2.27/angular-resource.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="//cdn.rawgit.com/mgonto/restangular/master/dist/restangular.min.js"></script>
</head>
<body>
<div ng-controller="IndexCtrl" ng-cloak>
<ul>
<li ng-repeat="person in people">{{person.Name}}</li>
</ul>
</div>
And the JS:
var app = angular.module('app', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.setBaseUrl('http://finance.yahoo.com/d');
});
app.controller('IndexCtrl', function($scope, Restangular) {
$scope.people = Restangular.all('quotes.csv?s=MSFT+GE&f=nab').getList();
});
I'm confused by this error because since this is a public API and POSTMAN can access it, I'd assume that the header is already present in the API server. Why would I get this error when requesting from my local?
Any help would be GREATLY appreciated.
Here's me making a JSONP request which fails because it's trying to receive a CSV file. I don't think restangular knows how to read CSV files either which is what you are attempting. I think you need to do the same thing as you are now but using the YQL API instead because I don't think this is going to work.
Anyway here's the code:
http://plnkr.co/edit/GokYqzJ0dXw86C6AM2UP?p=preview
The request (which goes through but fails due to the file type):
app.controller('MainCtrl', function($scope, $http) {
$scope.name = 'World';
$http.jsonp('http://finance.yahoo.com/d/quotes.csv', {
params: {
callback: 'JSON_CALLBACK',
s: 'MSFT GE',
f: 'nab'
}
}).success(function(response) {
console.log(response);
}).catch(function(response) {
console.log(response);
})
});

Resources