How to access the services from RESTful API in my angularjs page? - rest

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.

Related

Can HTTP Cloud function and event-driven Cloud function access same collection in Firestore?

I have an event-driven cloud function (written in Node.js) that creates video collection in Firestore whenever there are changes in Storage bucket. But when I tried to access the same data from a HTTP function, the API throws a 401 unauthorised error.
HTTP Function:
exports.getVideos = (req, res) => {
db.collection('video').get().then(querySnapshot => {
return res.status(200).json({
videos: querySnapshot.docs.map(doc => doc.data()),
total: querySnapshot.size
});
})
.catch(error => {
functions.logger.error('Error getting video details: ', error);
return res.status(500).json({ error });
});
};
API Response: 401 Unauthorized
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>401 Unauthorized</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Unauthorized</h1>
<h2>Your client does not have permission to the requested URL <code>/video/get-videos</code>.</h2>
<h2></h2>
</body>
</html>
I don't see any issues on the code side, so I was wondering what's the root cause of this.
It might be that different cloud functions are executed using different service accounts. And one of them has required IAM roles/permissions, and another - not.
Another option - can you check that all of that happens in one GCP project and both cloud functions are supposed to work with exactly one (and the same) firestore collection?

JCR_SQL2 example in Javascript?

I'm looking for some sample code using the AEM JCR_SQL2 API in server-side Javascript (NOT Java), i.e. code that starts with use(function() { ... }) and is loaded via data-sly-use=${...}.
All Google results are 100% Java based examples.
What I've already tried: Google "JCR-SQL2 js example" and variations.
Expected result: sample code in Javascript.
Actual result: lots of Java code :-(
If you wanna use server-side JS (what I don't recommend), then you only have to convert the syntax of the Java examples. You interact with the Java-Objects anyway. So the API is the same for JS as for Java. In case you have a HTL component and calling the JS via the Use-API, then several objects are already defined in your JS scope.
https://helpx.adobe.com/experience-manager/htl/using/global-objects.html
Here is an JS example to search all core components with a SQL-2 query:
use(function () {
var pageName = currentPage.name;
var title = currentPage.properties.get("jcr:title");
var resourceName = granite.resource.name;
var resourceTitle = properties.get("jcr:title");
var componentList = [];
var componentIter = resolver.findResources("SELECT * FROM [cq:Component] AS c WHERE ISDESCENDANTNODE(c, '/apps/core/wcm')", "JCR-SQL2");
while (componentIter.hasNext()) {
var compoenentRes = componentIter.next();
componentList.push(compoenentRes.getPath());
}
return {
pageName: pageName,
title: title,
resourceName: resourceName,
componentList: componentList
};
});
The component HTL code to use it, would be:
<div data-sly-use.info="info.js">
<p>page name: ${info.pageName}</p>
<p>title: ${info.title}</p>
<p>resourceName: ${info.resourceName}</p>
<p>core components: </p>
<ul data-sly-list.component="${info.componentList}">
<li>${component}
</ul>
</div>
PS: You probably know, but here you find the Use-API for JS:
https://helpx.adobe.com/experience-manager/htl/using/use-api-javascript.html
I'm not aware of any Web-API for JCR_SQL2 queries. You would have to implement your own Servlet in AEM (with Java), which would accept queries from external HTTP requests. Then you could call your servlet from your JS code via Ajax, and execute the query inside AEM with Java.
Maybe the Query Builder API is interesting for you. This query-language is already available from the outside, and can be called via Ajax. For testing and developing your queries you can use the Query Debugger:
Adobe Documentation:
https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/querybuilder-api.html
Query Debugger:
http://localhost:4502/libs/cq/search/content/querydebug.html
Query Debuger with Sample Query:
http://localhost:4502/libs/cq/search/content/querydebug.html?charset=UTF-8&query=type%3Dcq%3APage%0D%0Aorderby%3D%40jcr%3Acontent%2Fcq%3AlastModified%0D%0Aorderby.sort%3Ddesc
Sample Query called directly:
http://localhost:4502/bin/querybuilder.json?orderby=%40jcr%3acontent%2fcq%3alastModified&orderby.sort=desc&type=cq%3aPage

Javascript Routing in play Framework not working

I´m having a curious problem in my application when I use the Javascript Routing of Play Framework. This is the problem:
Screenshot
and this is my code:
class Application extends Controller {
import play.api.mvc._
import play.api.routing._
def javascriptRoutes = Action { implicit request =>
Ok(
JavaScriptReverseRouter("jsRoutes")(routes.javascript.ProcessController.retrieveAllProcess)
).as("text/javascript")
}
}
this is muy route file:
GET /javascriptRoutes controllers.Application.javascriptRoutes
GET /Process/All controllers.ProcessController.retrieveAllProcess
this is the html.scala file:
var option =
{ "url" : #routes.javascript.ProcessController.retrieveAllProcess,
...
}
Thank you so much :).
I think you're confusing the javascript routing with reverse routing.
Javascript routing
Javascript routing is meant to generate javascript code. The generated code defines functions that can be used in your javascript to generate urls at the client side. Since you've defined an Action returning the generated code, you could include it in your page by using
<script type="text/javascript" src="#routes.Application.retrieveAllProcess()"></script>
Note that this uses reverse routing to tell the html page which URL should be used for the script. :)
Then in your javascript code it can be used like so
var retrieveAllProcessRoute = jsRoutes.controllers.Application.retrieveAllProcess()
to generate a javascript object containing both the HTTP verb and url to the Application::retrieveAllProcess method.
Reverse routing
Reverse routing is used to generate scala code. This code is meant to generate URLs in views or Redirects to controller methods on the server side.
Since you're talking about a template (*.html.scala), you're talking about the server side of things. This means that you should use the reverse routing capabilities of Play. Below I've rewritten your javascript template snippet to use reverse routing:
var option = {
"url": #routes.Application.retrieveAllProcess,
...
}

How can I redirect an address starting with #!

I have a new wordpress site instead of my old Wix one.
in the old one there were page addresses like http://example.com/#!contact/ct07/ in the new one this page resides under http://example.com/contact
I've tried 3 redirections plugins but none works (Redirection, redirection editor, quick 301 redirect).
I have no access to the .htaccess file
On redirection it seems like the engine does not see the URL.
Any manageable idea besides JS ? I don't want to miss google juice
Browsers don't send the part after # to the server, so the server don't know about this part and won't be able to do the redirect.
So you have to do the redirection in javascript:
if (/^#contact\//.test(document.location.hash)) {
document.location = '/contact';
}
For SEO purpose, you may want to handle the _escaped_fragment_ parameter too
I had this problem a few weeks ago.
PHP does not get anything after hash tag, so it is not possible to parse request url and get hash. But JavaScript can.
Below you find my solution for WordPress redirects by hashtag #! :
(You should put this code in functions.php of your active theme):
function themee_hash_redirects() {
?>
<script type="text/javascript">
function themee_hashtag_redirect( hashtag, url) {
var locationHash = document.location.hash;
if ( locationHash.match(/#!/img) ) {
if ( hashtag == locationHash ) {
document.location.href = url;
}
}
}
// Examples how to use themee_hashtag_redirect
themee_hashtag_redirect('#!contact', '/qqq/');
themee_hashtag_redirect('#!zzz', '/aaa/');
</script>
<?php
}
add_action('wp_footer', 'themee_hash_redirects');

How to access access gadgets.* with OpenSocial

Is there a way to use gadgets.* in my JavaScript code if my content type is URL?
You could use the Proxied Content feature. That way you can access gadgets.* APIs from the content fetched from your own server.
<Module>
<ModulePrefs title="My App">
<Require feature="opensocial-0.9"/>
</ModulePrefs>
<Content view="canvas" href="http://www.example.com/myapp/canvas/index.html">
</Content>
</Module>
According to the OpenSocial specification (at least starting from 0.8 and later), the relative path link to JavaScript libraries of requested features should be passed in the content URL parameter. Search the OpenSocial specification for keyword 'libs' to get more information.
The problem still is that the path given in URL is relative, not absolute, and you would need to know the base URL where to append this parameter. The discussion thread here suggests to use a base URL "https://www-gm-opensocial.googleusercontent.com/gadgets/js/" and append the value of 'libs' as it is, but I've not successfully verified that. Code that we've used to fetch libraries for the OpenSocial gadget on iGoogle (with jQuery support) is:
var libsMatch = window.location.search.match(/[?&]libs=([^&]*)/);
if (libsMatch) {
var libArray = libsMatch[1].split(",");
$.each( libArray, function(i, val) {
$.ajax( {
url: "http://www.google.com/ig/f/" + val,
dataType: 'script'
} );
} );
}
NOTE, though, that not all APIs will be available this way, e.g., gadgets.io.* can't be enabled this way, others needs to be tested.