AngularJS loading JSON from URL via REST - json

I am still a bit new about AngularJS and just came across the topics about service, provider, and factory.
I have still problem(s) on:
How to load JSON response from server via REST.
Place the loading code in either service, provider, factory in which suits it best.
Provide encapsulation feature (getters/setters) in which $scope could watch the changes if the load was successful or not.
Please comment for clarifications.

The RESTful functionality is provided by Angular in the ngResource module.
It's better to use $http service for non restful resources
var phonecatServices = angular.module('phonecatServices', ['ngResource']);
phonecatServices.factory('Phone', ['$resource',
function($resource){
return $resource('phones/:phoneId.json', {}, {
query: {method:'GET', params:{phoneId:'phones'}, isArray:true}
});
}]);
The $resource service makes it easy to create a RESTful client with
just a few lines of code. This client can then be used in our
application, instead of the lower-level $http service.
Please check this link for additional details
https://docs.angularjs.org/tutorial/step_11

Related

Can we access data from an api call which is made by another app in angular js

There is some static data in json format available on a web page through a rest api call made by owner of that page.
Now i want to retrieve that data in my angular app as my angular controller also exists on that page.
Is that possible?
The rest api call is already made by the owner so i don't want to make a network call again?
If data is open to all
If the JSON is accessible to anyone on the internet then you can call it in with a http request.
for example http://www.w3schools.com/angular/customers.php is a page of JSON data that anyone can access, all you have to do is make the correct http request in your app and the data will come into it.
To do a http request create a controller with code like the following
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://www.w3schools.com/angular/customers.php")
.success(function(response) {$scope.names = response.records;});
});
this will add all of the data to the $scope.names.
Note
Code taken from w3schools here

Dynamic Json result from RestAPI not being returned to Angular controller

I have Json data being pulled from a REST API. On success I have created a simple alert that will display the Json results inside of an $http.get. I found a sample URL that points to Json data online for testing and I get the alert with the results just fine. But when I try to do this with my URL pointing back to the api, I get no results (not even an alert). However, when I take that same URL and put it into the browser, all of my Json data is there. Any ideas or thoughts on what might be causing this issue? Thanks.
JavaScript (with test Json data)
var myApp = angular.module('paladinMonitor', ["highcharts-ng"]);
myApp.controller('SizeCtrl', function ($scope, $http, $timeout) {
$http.get('http://ip.jsontest.com/?callback=showMyIP').success(function (data, status) {
alert(data)
});
I had something similar happen to me. Restful web services must use the Access-Control-Allow-Origin header to specify what origins are allowed to access the service. Without it, you can hit the web service successfully by putting the address directly in your browser but it won't work from your app. If your REST service is written in Java, you can see this question for details on how to add the appropriate headers. Other languages will use a similar mechanism.
My other guess is that the web service requires authorization to access. It works fine from your browser because at one time you provided the proper credentials and
your browser cached them. If your service does require authorization, see the "Setting HTTP Headers" section on this page for information on how to add the appropriate headers.
As Alvin Thompson mentioned, you have to set your access-control-allow origin and should also set your access-control-allow-headers, access-control-allow-credentials on the server side. In my case I had to do this in my WebAPIcontroller. This is because in order for CORS to work (cross-domain) you have to have the service 1 (RESTApi in my case) allow permissions for service 2(client) to receive call it. In order, to allow this I had to add the following NuGet packages
NuGet
- Microsoft.AspNet.Cors NuGet package
- Microsoft.Owin.Cors NuGet package
Once these were installed I went to my config file on the API project and added
API App_Start/WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
config.EnableCors();
}
Then in my controller that inherits the API controller I referenced the NuGet package I installed and enabled CORS on the client side and this is where you set you origin, headers and methods
YourController : ApiController
namespace YourNamespace.Controllers
{
[EnableCors(origins: "https://localhost:.....", headers: "*", methods: "*")]
public class YourController : ApiController
{
//The rest of your controller functionality
}
}
The rest of the issue I was having was how the Json Web Token variable is being passed into my javascript file. I am still working on this, I will post the answer to this as well when I figure it out.
To read more about the CORS issue, this was the best reference for me: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

Other technologies that can perform DTO request response like WCF

I have a WCF service that allows me make a request using an DTO and replies with a DTO for a WPF application. For example I pass a filter object for products which has a few properties for things I want to filter on and a couple of extras for paging, (the server will take care processing the filter object and getting the data) an example is like this.
public async Task<ObservableCollection<ProductListItem>> GetProductList(ProductFilter filter, int startIndex, int pageSize, string sortBy)
I am wondering if there exists any other technologies beside WCF that allow such an operation, From my preliminary research which may be quite off is that WebAPI uses the GET, POST, PUT verbs and routing rules which is quite different.
ServiceStack looks like it might be able to do this I can see on slide 37 at https://servicestack.net/features
it says.
List<Product> productOver2Bucks = client.Get(new FindProducts{PriceGreaterThan = 2})
Which seems pretty close but might still require Rest verbs as it uses a Get().
I don't know it it is FUD or not but I have been reading that soap over WCF is believed by some to be a legacy technology and JSON is the way of the future. So is there a replacement technology that will work with a method signature to the one I have above? That i could call from platforms such as Windows universal applications.
In ServiceStack if you design your Service with the Any method name, e.g
public object Any(Request request)
{
return new Response { ... };
}
This will allow calling this Service from Any HTTP Verb on any Format or endpoint (e.g. JSON, XML, MsgPack, Protocol Buffers, SOAP, Message Queue's, etc).
Also you don't need to define any [Route] for your Request DTO's since it will automatically fallback into using the pre-defined Routes when none are available.
public class Request : IReturn<Response> { ... }
public class Response { }
So with the above Service you can use ServiceStack .NET ServiceClients to call the API's using any verb, e.g:
var client = new JsonServiceClient(baseUrl);
Response response = client.Get(new Request { ... });
Response response = client.Post(new Request { ... });
When preferred you can also use the async API's, e.g:
var response = await client.GetAsync(new Request { ... });
var response = await client.PostAsync(new Request { ... });
Which if you don't care for using verbs you can use the generic Send API, e.g:
Response response = client.Send(new Request { ... });
Which just uses POST underneath, although it's highly recommended to use Get for "read only" queries as it will allow the Services HTTP responses to be cached by any intermediate HTTP Middleware or proxies.
Add ServiceStack Reference
Also if you're coming from WCF you'll also enjoy ServiceStack's, Add ServiceStack Reference which provides a number of advantages over WCF's Add Service Reference feature but still provides the same utility in being able to generate a typed API from a remote url for:
C# Add Reference
F# Add Reference
VB.NET Add Reference
TypeScript Add Reference
With more languages to follow.
Advantages over SOAP
Whilst ServiceStack still enables WSDL's, XSD's for your Services so they can be called from SOAP 1.1/1.2 endpoints for legacy compatible reasons - there are a number of reasons why using clean HTTP and JSON/XML API's are preferred.

Angular.js : CORS HttpInterceptor that transforms $http.get into $http.jsonp request transparently

I've been looking into if it's possible to create a web based version of my Chrome Plugin
now that it's relying completely on Trakt.TV's JSON API.
According to angular's documentation, it's possible to intercept HTTP requests at several levels, one is the HTTP Backend itself (mainly used for testing though) and the other is HTTPInterceptor.get
The basic idea is to wrap calls to Trakt.TV's JSONP api through http://json2jsonp.com/ and have them returned transparently to get around cross site scripting restrictions. This would not only be very useful for my own project, but for a lot of other people daeling with the same issues too (therefore i'll release the module after it's done, but I want to do it properly)
The basics should be simple:
Hook the $http.get request at the right level
Overwrite the original request made
Cancel an optional other request already set up
Hook it through $http.jsonp(http://json2jsonp.com/)
Return the original promise's success/fail when done
Questions:
Has anyone built anything like this yet? (Github searches revealed nothing)
Would you suggest using the HTTPBackend or the HTTPInterceptor?
why can't you just use the jsonp helper function?
httpBakend is a mockup service to fake a backend server is not used on live code. http interceptors would do what you want you just need to attach the callback function name to your request if the url contains what ever name you want to filter and then in the response interceptor you have to pass response to the callback function so the json to be evaluated. be aware that interceptors will inspect every request makde by angular which is not very eficien, unless you are only doing calls to the tv service.
like i said before a better approach is to use $http.jsonp function
https://docs.angularjs.org/api/ng/service/$http#jsonp
a word about interceptors they need to be defined as services and then be passed to HttpProvider during your apps configuration.

MarkLogic 7 REST API - Bad Request Error

I am building a webapp using AngularJS on top of a MarkLogic 7 XML database. I am using the REST API provided by MarkLogic to access the database. The code I'm using in my controller is as follows.
app.controller("mainController", function($scope, $http){
var addr = 'http://localhost:8011/v1/search?q=test&options=newtest';
$http({method:'GET', url: addr})
.success(function(data){
alert('Success');
console.log(data);
});
});
Now, when I open my view, a 'bad request' error is logged in the console.
OPTIONS http://localhost:8011/v1/search?q=test&options=newtest 400 (Bad Request)
angular.min.js:99
OPTIONS http://localhost:8011/v1/search?q=test&options=newtest No 'Access-Control-Allow-
Origin' header is present on the requested resource. Origin 'null' is therefore not
allowed access. angular.min.js:99
XMLHttpRequest cannot load http://localhost:8011/v1/search?q=test&options=newtest. No
'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null'
is therefore not allowed access. index.html:1
Are there any settings to be configured on the MarkLogic server to make the API accessible? Please help.
Thanks,
Krishna
Krishna, is your AngularJS code hosted by MarkLogic, or are you running it in node.js (via grunt, perhaps)? This looks like a cross-site scripting problem. Two solutions come to mind:
If you don't need a middle tier, MarkLogic can host the Angular code. Put it in the modules database of the app server on port 8011. Then the request is going to the same place the JS came from and the problem goes away.
If you want to keep a node layer, set up a proxy. Assuming you're using Grunt, you can see how I handled that in the Gruntfile.js of an app with the same stack.
Once you get past that error, you might consider moving the interaction with the MarkLogic REST API into a service. The Demo Cat application I linked to above has an early version of an MLRest AngularJS service; that might be a useful starting point.