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) {
...
});
Related
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.
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
My company uses SQL Server. I want to develop reporting dashboard for it, and I want to develop it using Nodejs + Angularjs.
I have this following code; can you give me a small example of
Retrieve data from SQL Server
Display in html page using Angularjs
Use Node.js for the serverside program.
I have a piece of code. which is not working.
//server.js
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/website'));
require('./app/routes.js')(app);
var server = app.listen(5000, function () {
console.log('Server is running..');
});
//router.js
module.exports = function(app) {
// Load index file
app.get('*', function(req, res) {
res.sendfile('./index.html'); // load the index from static files directory.
var sql = require("mssql");
// config for your database
var config = {
user: 'sa',
password: 'sqlserver',
server: 'FKHADER01',
database: "master"
};
// connect to your database
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query('select count(*) CT from sales', function (err, recordset) {
if (err) console.log(err);
// send records as a response
res.send(recordset);
var count = recordset[0].CT;
});
});
});};
//index.html
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"> </script>
<body>
<div ng-app="" ng-init="count='5'">
<p>The name is <span ng-bind="count"></span></p>
</div>
</body>
</html>
Please provide me any other best method , if you have
I understand you are able to get the data from Sql server in your server.js Page. You would now want to send the data to the views.
So what you can do is use a view engine like EJS (npm install ejs)
and app.set('view engine', 'ejs');
you can pass the data which you have in the "recordset" variable to
the EJS page. The rendering would look something like
res.render('./index.ejs',message:recordset , count :count)
You would also need to create an index.ejs file and copy all the
context of index.html to it. The .ejs can simply be created
by renaming index.html to index.ejs
In the index.ejs , inside script tags ,you can retrieve the
recordset & count as
<script>var rawQuery = <%message%>; var count = <%count%></script>
You can then apply angular to manipulate the data in rawQuery,count
and attach it to the scope in the required controller.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.count = count;
});
Hope this link helps.
https://scotch.io/tutorials/use-ejs-to-template-your-node-application
I understand you are able to get the data from Sql server in your server.js Page. You would now want to send the data to the views. So what you can do is use a view engine like EJS (npm install ejs) and app.set('view engine', 'ejs'); you can pass the data which you have in the "recordset" variable to the EJS page. The rendering would look something like
res.render('./index.ejs',message:recordset , count :count)
You would also need to create an index.ejs file and copy all the context of index.html to it. The .ejs can simply be created by renaming index.html to index.ejs
In the index.ejs , inside script tags ,you can retrieve the recordset & count as
<script>var rawQuery = <%message%>; var count = <%count%></script>
You can then apply angular to manipulate the data in rawQuery,count and attach it to the scope in the required controller.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.count = count;
});
Hope this link helps. https://scotch.io/tutorials/use-ejs-to-template-your-node-application
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>
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);
})
});