Make a get request with restful api in angularjs - javascript

It's my first question here, sorry in advance if there's a discussion of what i'm going to ask, already. I'm new to angularjs and I'm pretty sure this is not a big problem, but I don't understand what I have to do. I'm working with API teech.io and I would like to get some experience to learn how to use them. My problem is this: make a GET request via http (each user has an app key and an app Id), for example to materials. The documentation of materials says this:
A GET to /materials/:id fetches the material object.
GET /materials/:id HTTP/1.1 Host: api.teech.io Teech-Application-Id:
[app ID] Teech-REST-API-Key: [API key]
<!DOCTYPE html>
<html>
<head>
<!-- INCLUDE REQUIRED THIRD PARTY LIBRARY JAVASCRIPT AND CSS -->
<script type="text/javascript" src="js/angular.min.js"></script>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-responsive.min.css">
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="teechpadController2.js"></script>
</head>
<body>
the app.js is this one
var app = angular.module('TeechTest',[]);
The teechpadController is this
teechpad.factory('$api', function($http) {
var defaults = {
method: null,
url: null,
headers: {
'Teech-REST-API-Key': api.teech.io.apikey,
'Teech-Application-Id': api.teech.io.appid.
}
};
var req = function(method, url, config) {
defaults.method = method;
defaults.url = 'http://api.teech.io' + url;
var h = angular.extend({}, defaults, config);
console.log(heart);
return $http(heart);
};
return {
get: function(url, config) {
return req('GET', url, config);
},
put: function(url, data, config) {
defaults['Content-Type'] = 'application/json';
defaults['data'] = data;
return req('PUT', url, config);
},
post: function(url, data, config) {
defaults['Content-Type'] = 'application/json';
defaults['data'] = data;
return req('POST', url, config);
},
delete: function(url, config) {
return req('DELETE', url, config);
}
}
});
What I understood till now is that teechpadcontroller re-define the PUT-POST-DELETE-GET methods. Now, How can I use, for example, get method in my controller? Or Should I create an other controller and then use $app there? Sorry again for everything, I'm very new here and in angularjs. Last but not least, I work with JSON object(I think it was clear already)

In your Controller (where you inject this factory) you could use this factory called $api.
The exposed functions to this $api is the four functions returned in the returncaluse:
return {
get: function(url, config) {
...
},
put: function(url, data, config) {
...
},
post: function(url, data, config) {
...
},
delete: function(url, config) {
...
}
}
so in your own controller you could use it something like this:
JavaScript
angular.module('myModule',['TechTest']).controller('myCtrl',function($api){
var customUrl = "/PATH/TO/ENDPOINT",
customConfig = {}; // might not be needed.
$api.get(customUrl, customConfig).success(function(data){
$scope.apiResult = data;
});
})
HTML (which needs to know about your controller per usual)
<!-- include scripts -->
<body ng-app="myModule">
<div ng-controller="myCtrl">
<div>{{apiResult}}</div>
</div>
</body>
I hope I did not missunderstood your quetion.

Now, How can I use, for example, get method in my controller?
You can use your '$api' inside any controller you define by adding it to the injectables of that controller through
var app = angular.module('TeechTest',[]).factory('$api', function($http){ ... });
var controller = app.controller('ctrl', ['$api', function($api){ ... }]);
and then call your 'get' method by going: $api.get( ... ); inside your controller.
Watch out, you've defined 'h' and 'heart' on two different lines, this might just be a typo but it might trip you up!
Your function call to $api.get( ... ); will return asynchronously and you will get the result inside either:
$api.get( ... ).success(function(response){ console.log(response); }); //success
$api.get( ... ).error(function(response){ console.log(response); }); //failure
This is a deferred callback - look into the promise API for more in depth details. You may also want to look into resetting the defaults object every time so you guarantee you're working with a clean object each function call.
Any incorrectness then say and I'll update my answer :)

Related

HTTP Error 405.0 - Method Not Allowed while accessing web-api from angularjs app

I am creating a anjular js app where i have created a login page and i m authenticating it using web api. This is the controller which is returning json and it is running properly.
[Route("api/Customer/{id}/{pass}")]
public IEnumerable GetCustomer(string id, string pass)
{
var list = repository.Get(id, pass);
if (list != null)
{
return list;
}
else
{
return null;
}
}
this is the controller accessing the api in angular app (demoApi.js)
(function () {
'use strict';
var DemoApi = function ($http) {
var loginCheck = function (username, password) {
return $http.get("http://localhost:8115/api/Customer/" +username+"/"+password)
.then(function (response) {
return response.data;
});
};
return {
loginCheck: loginCheck
}
};
var app = angular.module("angularApp");
app.factory("DemoApi", DemoApi);
}());
this is the login controller(loginController.js)
(function () {
var app = angular.module("angularApp");
var loginController = function ($scope, $http, bankApi, $location) {
var userDetails = {
username: $scope.uName,
password: $scope.uPassword
};
$scope.login = function () {
DemoApi.loginCheck(userDetails.username, userDetails.password)
.then(onLogin, onError);
};
var onError = function (reason) {
$scope.error = "Could not fetch the data.";
};
var onLogin = function (data) {
$scope.details = data;
$location.path("/info");
};
}
app.controller('loginController', loginController);
}());
this is the index page where i have all the scripts linked
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="angularApp">
<head>
<title>Ebank</title>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-route.js"></script>
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<script src="lib/app.js"></script>
<script src="lib/bankApi.js"></script>
<script src="lib/loginController.js"></script>
<script src="lib/infoController.js"></script>
</head>
<body style="background-color:#333">
<div ng-view></div>
</body>
</html>
Provide me with a solution, why i m not able to call api from demoApi.js
I'm getting the response if i call this api directly from the html page but not getting response from demoApi.js
Most probably you bumped into CORS issue. You need to enable CORS. Follow below mentioned steps.
Open IISExpress config file applicationhost.config located at C:\Program Files (x86)\IIS Express\AppServer.
Search for "httpProtocol" tag. Inside it check if "customHeaders" tag exists. If not then add it.
Add following two tag inside "customHeaders" tag.
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
Alternatively you can run chorme browser in security disabled mode using following command on command prompt and try accessing your site from there.
Full path to chrome.exe --disable-web-security --user-data-dir
Note its just workaround to test your application however in production deployment you need to enable CORS.

using factory in the controller return undefined

I am trying to send value from my view to the controller using function inside ng-click , then use that value to pass it to my factory which goint to pull data from rest api link , but the value im sending return nothing without errors, here is my code
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, idService) {
$scope.getSo = function (id){
$scope.myIDs = idService.getID(id);
};
});
app.factory('idService', function($http,$q) {
var oGetID = {};
oGetID.getID = function(id) {
var deferred = $q.defer();
$http.get('http://citysdk.dmci.hva.nl/CitySDK/pois/'+id).then(function(response){
deferred.resolve(response.data);
});
return deferred.promise;
};
return oGetID;
});
</script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
send variable
{{myIDs.location.address.value}}
</div>
</body>
</html>
this is the console result of the response
Asynchronous call doesn't work the way you are expecting here. Then happens asynchronously and they return return the data based on API server call. You should expect value after a ajax succeed, by putting .then over it. As internally $http method's return promise.
idService.getID(id).then(function(response){
alert(response);
$scope.myIDs = response;
})

Angular js does not get json response from node js

I am trying to establish REST connection between node (middleware) and angular (UI). However, the json is displayed on the browser rather than being routed via the angular controller/html
Node/Express router.js
router.get('/members', function(request, response){
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Methods", "GET, POST");
response.setHeader('Content-Type', 'application/json');
var dbdata = [];
var str;
db.get('_design/views555/_view/app_walltime', function (err, body) {
if (!err) {
body.rows.forEach(function(doc) {
dbdata.push({name: doc.key, walltime:doc.value});
});
console.log(dbdata);
response.json(dbdata);
Angular controllers.js
'use strict';
var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.config(['$httpProvider', function($httpProvider, $routeProvider, $locationProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
phonecatApp.controller('PhoneListCtrl', function ($scope, $http, $templateCache) {
alert('asdsad');
$scope.list = function() {
alert('hereh');
var url = 'http://192.168.59.103:8072/members';// URL where the Node.js server is running
$http.get(url).success(function(data) {
alert(data);
$scope.phones = data;
});
};
$scope.list();
});
html - testangular.js
<html ng-app="phonecatApp">
<head>
<meta charset="utf-8">
<title>My HTML File</title>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css">
<script src="/bower_components/angular/angular.js"></script>
<script src="/bower_components/angular-route/angular-route.min.js"></script>
<script src="js/controllers.js"></script>
</head>
<body ng-controller="PhoneListCtrl">
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<ul class="phones">
<li ng-repeat="phone in phones | filter:query">
{{phone.name}}
<!--<p>{{phone.walltime}}</p> -->
</li>
</ul>
</div>
</div></div>
What is see is the following on the browser
[{"name":"app1","walltime":"1050"},{"name":"app2","walltime":"30"}]
I seem to be missing some configuration to let node and angular communicate. Please let me know what I am doing wrong.
What you see on the browser's window is a JSON object, that is the result of your request.
With the line $scope.phones = data;, you're simply assigning to $scope of Angular the data object, without actually parsing it.
The result is that Angular is not able to understand in the ng-repeat directive what actually {{phone.name}} and {{phone.walltime}} are and the JSON string is shown.
In order to have the ng-repeat directive working as expected, you have to parse first the JSON object, process it (creating for example a custom object and assigning its properties) and then assign it to $scope object.
You could perform the parse using something like
JSON.parse(data);.
Please have a look at this question for further information.
Or even using the Angular's builtin function angular.fromJson(data).
An example could this:
$http.get(url).success(function(data) {
alert(data);
$scope.phones = angular.fromJson(data);
});
};
Test this :
var url = 'http://192.168.59.103/members';
$http.get(url).then(
function(response) {
console.log('success',response)
},
function(data) {
// Handle error here
})

How to set Angular JS $resource path (I'm getting 404s here)

I'm a noob to AngularJS and trying to set up a simple webapp in order to test, if the framework suites our needs. I've read the API reference and did the tutorial. Unfortunately the way path and locations are set and handled on $resource is not quite well explained there.
The problem I am facing is that I always get a 404 when I give $resource the relative path as described in the tutorial.
Here is my set up:
I have cloned the AngularJS phone cat app and threw away their phone stuff but made use of their structure to bring in my own logic. My index.html looks as follows:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>testapp</title>
<link rel="stylesheet" href="css/bootstrap.css">
<script src="lib/angular/angular.js"></script>
<script src="lib/angular/angular-resource.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="testapp">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="#">Testapp using AngularJS</a>
</div>
</div>
<div ng-view></div>
</body>
First trouble was that AngularJS doesn't seem to give any advice on how to oauth to a RESTful API, and their tutorial only gives a "dream scenario" of a server delivering hard-coded JSON, so I have hacked into their web-server.js in order to let the node.js server handle the API calls and return the resulting JSON. For oauth I did so successfully, yet for further API calls, it doesn't work.
Here's my hack:
StaticServlet.prototype.handleRequest = function(req, res) {
var self = this;
var path = ('./' + req.url.pathname).replace('//','/').replace(/%(..)/g, function(match, hex){
return String.fromCharCode(parseInt(hex, 16));
});
var parts = path.split('/');
if (parts[parts.length-1].charAt(0) === '.')
return self.sendForbidden_(req, res, path);
/* Hack for RESTful API calls. */
var post = '';
var query = qs.parse(req.url);
if (req.method === 'POST') {
var body = '';
req.on('data', function(data) {
body += data;
});
req.on('end', function () {
post = JSON.parse(body);
console.log(post);
// method name is part of the parameters
// apiRequests is the module handling the API requests
apiRequests[post.method](post, res);
});
} else if (query.api === 'api') {
var query = qs.parse(queryString);
// method name is part of the parameters
// apiRequests is the module handling the API requests
apiRequests[query.method](queryString, res);
} else {
fs.stat(path, function(err, stat) {
if (err)
return self.sendMissing_(req, res, path);
if (stat.isDirectory())
return self.sendDirectory_(req, res, path);
return self.sendFile_(req, res, path);
});
}
}
It's really just an ugly hack, but anyways. The login POST request is delegated to an oauth call and the api GET requests are delegated to the proper api request methods, the rest is handled the same way as web-server.js did before.
The trouble is, the handleRequest method is never called.
Here is my client side service code making the call:
return {
fetchCommunications : function ($scope) {
var parameters = {
'api': 'api',
'method': 'communications',
'bearer':userData["access_token"],
'chiffre':userData["chiffre"]
}
var resource = {
r : $resource('communications', {}, {
query: {method:'GET', params:parameters}
})
}
var d = resource.r.query();
console.log("Communications: " + d);
return d;
}
And this is the error message from the server console:
GET /app/communications?api=api&bearer=d6a348ea-0fe5-46fb-9b5e-13d3343c368d&chiffre=0000006F&method=communications Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
404 Not Found: /app/communications
This is exactly the path I'd expect to be called - but why is it 404?
I can avoid the 404 by configuring $resource like this:
var resource = {
r : $resource('index.html#/communications', {}, {
query: {method:'GET', params:parameters}
})
Which doesn't work either, since everything after the hash is omitted from the path. Besides, why would I need to have index.html within the path?
I have the feeling that I am missing something pretty obvious here and am therefore doing something pretty dumb. Anyone with any ideas? Is it something related to the configuration of node.js (never had this trouble before)?
Many thanks in advance!

Dynamically load jQuery templates

For jQuery template:
http://api.jquery.com/category/plugins/templates/
I want to be able to dynamically load the templates from a server, rather than predefining it on the page.
The demos I saw on the projects are using predefined templates. After some research I found out that it is possible.
I try doing this and it doesn't work:
<script src="child.html" type="text/x-jquery-tmpl"></script>
I tried doing this and it doesn't work:
$(function () {
$.get("child.html", function (data) {
//Add template
$.template("tmplChild", data);
});
//template binds before async call is done
$.tmpl("tmplChild").appendTo("body");
});
And finally, I have get it down to the following hack:
so.html (This is the main page):
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script>
<script type="text/javascript" src="so.js"></script>
<script type="text/javascript">
$(function () {
initTemplates(templateReady);
});
function templateReady() {
$.tmpl("tmplChild").appendTo("body");
}
</script>
</body>
</html>
child.html (This is the child template)
<h1>Child Loaded</h1>
so.js (This is my hack for ajaxly loading the js templates)
function initTemplates(callback) {
var templateUrl = "child.html";
var templateName = "tmplChild";
initTemplate(templateUrl, templateName, callback);
}
function initTemplate(url, name, callback) {
var opts =
{
type: "GET",
url: url,
dataType: ($.browser.msie) ? "text" : "xml",
success: function (data) {
xmlCallback(data, name, callback);
},
error: function (x) {
xmlCallback(x.responseText, name, callback);
}
}
$.ajax(opts);
}
function xmlCallback(data, name, callback) {
if (typeof data != "string") {
if (window.ActiveXObject) {
var str = data.xml;
data = str;
}
// code for Mozilla, Firefox, Opera, etc.
else {
var str = (new XMLSerializer()).serializeToString(data);
data = str;
}
}
//only takes strings!
$.template(name, data);
callback();
}
And here's what I don't like about it.
This doesn't work on Chrome
It seems like a lot of code just to load some template
I lost the ability to use $(document).ready(). I must now put all my code in this templateReady() method to be "template safe".
Is there a way around this?
Thanks,
Chi
Just load the template body as simple text and forget about putting it in a dummy <script> block. You can use $.tmpl(body, params) to populate the template and turn it into a string for appending to the DOM.
The whole thing with "not really script" <script> blocks is just a convenience useful in some situations.
edit — example:
$.get("/some/url/for/a/template", function(templateBody) {
var expandedTemplate = $.tmpl(templateBody, { param1: 0, param2: "Hello World" });
});
If the goal is to fetch a unique template each time you get data via ajax, then you might try fetching the template at the same time and include it in your data, that is if you have the luxury of modifying the returned object (anonymous object in .Net). Then you can store the template anywhere you want and you only need 1 ajax call for both the data and the template.
Refer here:
https://www.npmjs.com/package/jlate
use CDN:
<script src="https://cdn.jsdelivr.net/combine/npm/lodash,npm/jlate#0.0.2/jlate/JLate.min.js"></script>
HTML Code:
<body>
<div>
<jlate id="my_temp" src="template/jlate_title.html" type="template">
Loading...
</jlate>
</div>
</body>
Javascript:
$$("#my_temp").jlate({ title: "sample title"});

Categories

Resources