Calling an external rest service from Alfresco Share page - javascript

I have created a rest service in a java application . I need to call this rest service on the click of a button in Alfresco Share page . How do i approacj it . Can i directly call the service with the url ?

You can add a custom endpoint to SURF & use the SURF Proxy-Servlet:
Example Flickr Endpoint
share-config-custom.xml:
<alfresco-config>
<config evaluator="string-compare" condition="Remote">
<remote>
<endpoint>
<id>flickr</id>
<name>flickr - unauthenticated access for oembed resolution</name>
<description>Access flickr to resolve URLs to embed presentations.</description>
<connector-id>http</connector-id>
<endpoint-url>http://www.flickr.com/services</endpoint-url>
<identity>none</identity>
</endpoint>
</remote>
</config>
</alfresco-config>
In Browser JS Code just use the flickr endpoint via PROXY, e.g. add a new va PROXY_FLICKR_API :
var PROXY_FLICKR_API = Alfresco.constants.PROXY_URI.replace("/alfresco/", "/flickr/");
Alfresco.util.Ajax.jsonRequest(
{
method: Alfresco.util.Ajax.GET,
url: PROXY_FLICKR_API + "add your concrete URL",
successCallback:
{
...
},
failureCallback:
{
...
}
});
You should add your var PROXY_FLICKR_API JS declaration via SURF Extension mechanism - your target markupid is (more details http://blogs.alfresco.com/wp/developer/2012/05/22/customizing-share-javascript-widget-instantiation-part-1/):
<#markup id="yourid" target="resources" action="after">

Related

Rails json view into javascript function

I am storing some json data in an active-record session so have created a route and controller action which renders fine in the browser but when I try and pass the route into a JavaScript function the response in browser(chrome) network tab is null
Controller
class DataFilesController < ApplicationController
def show
render json: session[:my_data]
end
end
Route
get 'data-file.json', to: 'data_files#show', as: :data_file
Javascript function (in view)
= content_for :javascript do
:javascript
accessibleAutocomplete({
element: document.querySelector('#autocomplete-wrapper'),
id: 'autocomplete',
source: openregisterPickerEngine({
url: "<%= data_file_path %>"
}),
templates: {
inputValue: inputValueTemplate,
suggestion: suggestionTemplate
}
});
The openregisterPickerEngine library uses the fetch Request object, which by default does not send cookies. This means that your DataFilesController endpoint does not get the session ID in the users cookie and the session object is null.
Request.credentials needs to be set: https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials
Unfortunately the Request object is created in the library code which you don't directly control: https://github.com/alphagov/openregister-picker-engine/blob/master/src/index.js#L294
You either need to redesign the code so that the data endpoint does not need the session, or fork or modify that library (or stop using the library and craft your own fetching and parsing code).
Edit: actually the latest version of the library uses xhr while the older version you were using calls fetch. So the simplest "solution" is to upgrade the library: unlike fetch, xhr sends cookies with same-origin requests by default.

In Angularjs how do I load the same javascript file but pass different keys for different environment (Test, beta, prod)

in Angularjs in a html page I need to load an external javascript file:
<script src="https://www.my-url.com/js/my.js?Key=xxxxxxxx"></script>
But based on different env (test, beta, prod), I will have different Key.
How can I implement this like what we usually do using web.config in .net?
Edit:
I saw some answers, but seems not exactly what I need. so I elaborate my environment: I have a client side which is pure html and Angularjs, my server side is an Asp.net Web API web service. When I talk about web.config in the original post, I don't mean put the key in web.config, but something conceptually similar. I want this "config file" on the client side, not on my Web API.
You can use gulp-replace and automate it on your build time.
There are two issues to solve:
Getting web.config values into the angular app
Making use of the config to download a script
1. Getting web.config to the app:
I've detailed in a blog post the method I use. Essentially, use a custom angular provider in the applications .cshtml file. This will load all web.config items with the prefix of client:...
Used by the MVC controller:
public static class ApplicationConfiguration
{
private const string ClientAppSettingPrefix = "client:";
public static object GetClientConfiguration()
{
var clientConfiguration = new ExpandoObject() as IDictionary<string, Object>;
// Find all appSetting entries prefixed with "client:"
foreach (var key in ConfigurationManager.AppSettings.AllKeys.Where(key => key.StartsWith(ClientAppSettingPrefix)))
{
// Remove the "client:" prefix before adding to clientConfiguration
clientConfiguration.Add(key.Replace(ClientAppSettingPrefix, String.Empty), ConfigurationManager.AppSettings[key]);
}
return clientConfiguration;
}
}
Script added into the app's .cshtml file:
<!-- Inject the configuration -->
<script type="text/javascript">
(function() {
angular.module('client.config', [])
.provider('applicationConfiguration', function() {
var config = #Html.Raw(JsonConvert.SerializeObject(Model, new JsonSerializerSettings {ContractResolver = new CamelCasePropertyNamesContractResolver()}));
return {
config: config,
$get: function() {
return config;
}
};
});
})();
</script>
So now you can use it in you add as a normal dependency:
angular.module('app', [
// Add as a dependent module
'client.config'
])
.config([
'applicationConfigurationProvider', 'dataServiceProvider', function(applicationConfigurationProvider, dataServiceProvider) {
// Set the api root server configuration
dataServiceProvider.setApiRootUrl(applicationConfigurationProvider.config.apiRoot);
}
]);
2. Making use of config to download script
As suggested in other answers, use JQuery's getScript() function.
Other SO answers also suggest using a simple injection into the head if you don't want to depend on Jquery. Take a look at Single page application - load js file dynamically based on partial view for ideas
You have couple of options here.
Option 1:
Use Angular's http service to get script files dynamically as String and then use eval() function to execute resulting String.
References: eval Angular $http service
Option 2:
Use JQuery's getScript method
Example:
var keys={ 'prod':'prodKey',
'staging:='stagingKey',
'dev':'devKey'
}
//Assuming you have an variable storing modes like prod, staging or dev
var url='https://www.my-url.com/js/my.js?Key='+keys[ENVT.MODE];
$.getScript( url, function( data, textStatus, jqxhr ) {
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Script loaded successfully" );
});
Reference: getScript

How do Java REST calls relate to the front end of a Web Application?

I am aware of how REST calls work from within a Java Web application. E.g. when a URL is reached its method will be called using HTTP.
For example:
#GET
#Path("people/{id}")
public Response getPersonWithId(#PathParam("id") id) {
//return the person object with that Id
}
What I am unsure of is how this links to the front end?
Is the role of the UI ( i.e. javascript ) just to take a user to the specific URLs so that the back end methods can be called?
E.g. if a user presses a "get details" button, does the button just redirect them to this URL that deails with returning the details, and the back end functionality is then called?
WebService is not actually linked or tied to the front end similar to webapp. Instead, webservice is a service that provides result in the form of JSON/XML, Plain text Format according to request type(get, post, update, delete) and hence, the service can be used by any multiple front end application(not only web application but also smartphone app, desktop app etc.). Also, webservice can be on totally different server.
Let me give you a scenario:
Suppose, you have an front end web site ABC-Website and a backend
webservice on host: www.xyzservice.com/api with following methods:
/product - get request that return all product as list in json format.
/product/id - get request return product detail given id in json
format.
Now, if you simply type in browser www.xyzservice.com/api/product then
all product list will displayed in json format in the browser. That means, You can also read data from webservice directly in browser without front end system and i.e. webservice is not linked/tied to any front end.
Now, you want to use this webservice in your ABC-Website to display all the product list:
You call www.xyzservice.com/api/products and get JSON object that you can use to display in your html page.
<button type="button" onclick="getProducts()">Click Me!</button>
function getProducts(){
$.ajax({
type : "GET",
contentType : "application/json",
url : "http://www.xyzservice.com/api/product",
dataType : 'json',
timeout : 100000,
success : function(data) {
// now you have "data" which is in json format-same data that is displayed on browser.
displayDate(date);
},
error : function(e) {
//do something
},
done : function(e) {
//do something
}
});
}
function displayDate(){
//your codes to parse and display json data in html table in your page.
}
Lets say that your client is a website and you have a Java API.
In the javascript of your website you could do a request to the backend to retrieve the data and then present it to the user. Your javascript (using jQuery as an example) could look like the following:
// here it prints the data retrieved from the backend route (/people/{id}
$.get('http://localhost:3000/people/3',function onDataReceived(data) {
console.log(data);
})
As pointed out, jQuery is not necessary. Here is an example using regular javascript:
this.getRequest('http://localhost:3000/people/3', function onReceived(data) {
});
function getRequest(url, callback)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
in javascript, usually you want to do these request at the background your webpage.
Im gonna try to explain this with an example:
Imagine you have a page that displays a list of cars for sell which can be fetched from the web service provided by java back-end. The back-end have an url that will respond to GET method with a JSON (or XML) object.
What you have is a HTML file where you write a structure for the displayed data and also includes a javascript file that asynchronously calls this webservice, GETs the data, parses the JSON and then it can manipulate it to the form you want to display it on the page.
In different example you can validate forms on the background, or save the forms or do any other stuff that works with the web service API.
For making these asynchronous request you can use different libraries.
Most used is ajax included in jQuery framework or fetch as n standalone library.

cannot connect to Web API

I am new to WebAPI programming .Here is what have I done
Created ASP.NET web Application SampleWebApiProject in Visual Studio 2013
under .NET Framework 4.5.2
Selected MVC and checked Web API under [Add Folders and core references for].
using Nuget package installed knockout.js ,knockout-validation.js etc etc.
In my code for Login.cshtml I have html button
<div>
<button type="button" class="btn btn-info" data-bind="click:$parent.login">
Login
</button>
</div>
And on my click button I have
self.viewModelHelper.apiPost('api/account/login', unmappedModel,
function (result) {
}
And I have created API Controller called AccountApiController
public class AccountApiController : ApiController
{
[HttpPost]
[POST("api/account/login")]
public HttpResponseMessage Login(HttpRequestMessage request, [FromBody]AccountLoginModel accountModel)
{
return null;
}
}
However when I inspect the click event in Chrome developer tools I get an error response
POST http://localhost:64436/api/account/login 404 (Not Found).
this is my WebApiConfig
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Am I working with right type of application ?
Screenshot
Try:
self.viewModelHelper.apiPost('api/accountapi/login', unmappedModel,
function (result) {
}
and API Controller
public class AccountApiController : ApiController
{
[HttpPost]
[POST("api/accountapi/login")]
public HttpResponseMessage Login(HttpRequestMessage request, [FromBody]AccountLoginModel accountModel)
{
return null;
}
}
Your account controller is named accountapi and not account, so webapi can't find any controller called account.
I'm not sure, but your parameters look wrong in your webapi controller...
Why would you add HttpRequestMessage as a parameter?
You have called your controller AccountApiController and so api/account/login should be accountapi/login
Web API has a strict calls when it comes to MVC architecture.
If you call POST. It means that the API will really CREATE a new Entity, and Does NOT, make other request to be returned.
So meaning, the WebAPI is not custom API function Call that you thought it might be.
It is different from creating an individual API to Creating an web API inside an MVC Application.
Here is are some Notes.
GET : Retrieve an entity
PUT : update an entity
POST : create a new entity
DELETE : remove an existing entity.
so let us say you have an API for Account Models. I will say Models cause when creating an Web API. You need a Model. Unless you're creating your custom API. Outside the MVC.
Now you did this. api/account/test
What it will do is use the [GET] function.
Whatever function you have in the account controllers that have a Data Annotation of [GET] will be executed. And return you something.
And No. Don't use Login as the name of the Method just use GET as you can't really tell the Web API which function to use. It WILL use the one with the GET data annotation. So entering
api/account/ login <---- this will not call the login method, it is entering a string data to be passed to the Get Method.
[HttpGet]
public IEnumerable<string> Get()
{
return "No Value";
}
[HttpGet("{id}")]
public IEnumerable<string> Get(int id)
{
return "There is a value";
}
Now if you want the POST to be Called. Simply create a A Form that has a method of POST. Or JQuery Javascript and call generate the POST method for them. You can't write the Method call in the address bar. You just have to use the right kind of request to call the specific function or function with overload.

Facebook Search API Untrusted Connection

I am trying to search the Facebook API from my application using javascript FB.api(url, success function) and the JSON object that comes back contains the error: "Search queries are unsupported for this connection."
The url I'm using is: "https://graph.facebook.com/search?q=Bamboo&type=page&access_token=", which works when I'm testing it in browser
Why is my search unsupported???
The problem is your url. You only put your graph api command in the url parameter, thus the "https://graph.facebook.com" shouldn't be included.
For using the search call,
var urlCall = "/search?q=Bamboo&type=page&access_token=";
FB.api(urlCall, function(response) {
//you code to execute
});
and not the following
url = "https://graph.facebook.com/search?q=Bamboo&type=page&access_token="

Categories