Parsing a JSONP file in AngularJS - javascript

I'm new to Angular and also relatively new to the JSONP format. In my code, I set up a factory to read in the JSONP file - and I get back the data variable as the JSONP data properly
$http.get('someJSONFile').success(function(data){
console.log(data);
});
The console log gives me back the following:
states([{"code":"AL","name":"Alabama"},{"code":"AK","name":"Alaska"},{"code":"AZ","name":"Arizona"},{"code":"AR","name":"Arkansas"},{"code":"CA","name":"California"},{"code":"CO","name":"Colorado"},{"code":"CT","name":"Connecticut"},{"code":"DE","name":"Delaware"}])
So - I'm stuck on what to do now. I have a data object that contains a function. I need to parse out the JSON from this function - but not sure how to do it.
I have read in other places that I need to declare a function somewhere in my controller or factory called
function states(results)
{
// what is in results should be the JSON data I crave
}
But even if I do that, I don't think it ever executes - so I am not sure what I should do at that point to get the JSON data into an object that I can use.
The full file I am trying to parse is http://massachusettswebdesigns.com/states.json
Any help is appreciated!

Angular $http service provides a method to consume JSONP endpoints. In your case this should work:
$http.jsonp('someJSONFile').then(function(data) {
console.log(data)
});
Behind the scene, Angular will create a globally accessible function that will receive data, parse and pass further, so you don't need to worry about creating functions yourself.

What looks like your trying to do is standard JSON not JSONP, JSONP will require a callback and is only required if getting data from a different domain, ie a API service
Also the console log output you give is not valid JSON.
//init app
var app = angular.module('MyApp',[]);
//setup a factory for the data handling
app.factory("Data",function($http){
return {
getData:function(type){
return $http.get(type).
then(function(result) {
return result.data;
});
}
}
});
//in a controller 'call' the factory for the data
app.controller('main', function main($scope, Data) {
//other stuff
Data.getData('someJSONFile').then(function (data) {
$scope.jsonData = JSON.parse(data);
});
//other stuff
});

So my error was a stupid one. The JSON file was giving me the name of a custom callback I had to define. Once I did this, all worked. . . . here's the code
angular.module('locationApp')
.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.states = [];
$scope.cities = [];
// Function for the States callback on the JSON files provided
window.states = function (data)
{
$scope.states = data;
};
// Get the State JSON file.
$http.jsonp('http://locationinc-mapping-demo.herokuapp.com/states.json');
}]) // end of MainCtrl

Related

Basic REST calls to WordPress V2 API with Angular.js

I'm trying to get a basic query going with the new V2 API and Angular in WordPress 4.4.1. Perhaps someone can help me understand why the URL, /wp-json/wp/v2/posts, gives a JSON response with a 404.
Browsing to that URL gives me JSON like this:
{"code":"rest_no_route","message":"No route was found matching the URL and request method","data":{"status":404}}
And here is the JavaScript I'm using to make that .GET
var base = 'http://localhost:8888/recruitler';
var posts = '/wp-json/wp/v2/posts';
var user = '/wp-json/wp/v2/users/'; // append user id
var s = '/wp-json/wp/v2/posts?filter[s]='; // append search term
// basic HTTP call with Angular
var app = angular.module('app', ['ngRoute'])
app.factory('myService', function($http) {
var myService = {
async: function() {
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http.get( base+posts ).then(function (response) {
// The then function here is an opportunity to modify the response
console.log(response);
// The return value gets picked up by the then in the controller.
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return myService;
});
app.controller('MainCtrl', function( myService, $scope ) {
// Call the async method and then do stuff with what is returned inside our own then function
myService.async().then(function(d) {
$scope.data = d;
});
});
UPDATE:
This must be a local environment issue. Live websites work just fine. I've tested and this issue persists on all my local WAMP and MAMP dev sites. Restarting the server and or checking this answer got it working.
the factory looks right, according to the rest-api docs you need pretty permalinks plugin as well in order to rest-api plugin use custom url rewrites https://wordpress.org/plugins/rest-api/installation/

Passing data from server to angular

Sorry, I'm a newbie at this
Let's say i have the following in node express
router.get('/:name', function(req, res, next) {
res.render("test", {test:req.test});
});
how to do I get the angular to pick up the test variable?
i tried doing in the html page
<div ng-controller='UserCtrl'>{{ data }}</div>
<script>
var test=!{JSON.stringify(test)};
</script>
then on the angular page
productApp.controller('UserCtrl',function UserCtrl($scope){
$scope.data=test;
});
the req.test looks like this
[
{
name: 'test'
}
]
the 'data' shows empty everytime.
thank you for your help
If you want Angular to talk to a server, the most common way is through an AJAX request. Angular has a whole service to help you with this communication.
https://docs.angularjs.org/api/ng/service/$http
The first example pretty much does exactly what you are looking for:
$http({
method: 'GET',
url: '/testName'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
It uses promises for the response. Just add your actions in the proper call back function and away you go.
You will need to use ajax call from an angular script or service in order to get the express js backend response.
You can create a service like below -
productApp.service("API", function($http){
this.callAPI = function(name){
return $http({
url : "localhost:3000/"+name,
data : "", // pass data if any here
method: "get"
});
};
});
Then you will need inject this service in your controller and call like below -
productApp.controller('UserCtrl',function UserCtrl($scope, API){
//$scope.data=test;
// call service api here
API.callAPI("some name").then(function(response){
$scope.data = response;
}, function(){
// error goes here
});
});
Also, you can change your express js app to send the JSON data as follows -
res.json({...}); // instead of res.render(..);
Inside your express res.json() is, in my opinion, the best option you have since any object passed to it will be converted to JSON other way you can do it like you've done but render is more suited to html where you have to render a nice little view for the client or there is some sort of manipulation involved before sending the JSON on the wire or the json is too big and you don't want to make you router file dirty and rather delegate that to a view file.. else res.json() is a very neat way to do it.
Modify your controller code like:
productApp.controller('UserCtrl',['$scope', '$http' , function($scope, $http){
$http.get('/test').then(
function(response){
$scope.data = test;
},
function(err){
console.error(err);
}); //'/test' <- this is the url;
//$scope.data=test;
}]);
and remove this from your code
<script>
var test=!{JSON.stringify(test)};
</script>
I would recommend doing an $http service call to receive this variable BUT if you truly want this variable/data rendered directly in to the page and available in the controller, you should consider doing the following:
In the rendered/returned HTML:
<head>
...
<script>
angular.module('myAppConfig', [])
.value('MyTestConfig', !{JSON.stringify(test)});
</script>
</head>
<body ng-app="myApp">
...
<div ng-controller='UserCtrl'>{{ data }}</div>
...
</body>
This will setup an injectable configuration value called 'MyTestConfig'. Ideally, this should be part of a bigger object or service so you could do things like Config.apiPath or Config.getStaticResource('my-resource.png')
Your controller will now look like this:
productApp.controller('UserCtrl', function UserCtrl($scope, MyTestConfig){
$scope.data = MyTestConfig;
});
and your original modal definition will look something like this:
angular.module('myApp', ['myAppConfig']);
You may need to shuffle around where the script tag is depending on how you have configured your views. This will also only work before injection has been finalized, aka, this will not work for partials.

Error returning JSON from A.P.I request in angular.js

I am beginning my first angular.js app. I have written code to call a spanish rhyming dictionary A.P.I. In this code I log the JSON response to the console. However there is an error when I run this code. The console doesn't give me the specific error but it concerns my app.js file
Here is the website for the A.P.I-
Rhyme Searcher
Here is the repository with my code: https://github.com/Renniesb/rap_in_a_box
Here is my app.js code:
var rhymeApp = angular.module('rhymeApp', ['ngResource']);
rhymeApp.controller('rhymeView', function ($scope, $resource) {
$scope.rhymeApi =
$resource("http://store.apicultur.com/api/rima/1.0.0/flor/true/0/200/true",
{callBack: "JSON_CALLBACK"}, { get: {method: "JSONP"}});
$scope.rhymeResult = $scope.rhymeApi.get();
console.log($scope.rhymeResult);
});
$resource.get() is asynchronous which means that you need to provide a callback function to process the API response. Try using
$scope.rhymeApi.get({}, function(result) {
console.log(result);
});

Extract JSON object from $resource.get promise

I have just started exploring AngularJS. Is there any way by which I can extract the original JSON returned from server?
I am trying to get some data using $resource.get from a WebAPI. The returned promise contains some additional properties compared to my original JSON.
When I assign this object (returned from $resource.get) to some of my Javascript controls (like DHTMLX Scheduler), it does not work correctly but if I use $http it returns pure JSON and the control works perfectly.
I am more interested in using $resource as it has been used in the rest of the Angular controllers.
Let's say you have a service that's defined using a resource:
app.factory('LoginService', function($resource, API_URL) {
return $resource(API_URL + '/login.json');
});
Then elsewhere in a controller (for example) you want to use that service:
var loginRequest = LoginService.get({
email: email,
password: password
}).$promise;
loginRequest.then(function onSuccess(response) {
// access data from 'response'
var foo = response.foo;
},
function onFail(response) {
// handle failure
});
The key is that you need to access $resource.get().$promise, not $resource.get().

How to load JSON file from S3 using Angular $http.jsonp

I am loading JSON file from S3. File is loading successfully but problem is, I cannot access AnglarJS modules($scope, services and etc) in my callback function because it is written outside angularJS. Is there a way to access $scope in my callback?
AngularJS code
var url = "http://my_s3_url/abc/v1/klm/my.json"
$http.jsonp(url);
my.json
jsonp_callback({name:"xyz",age:2})
callback
<script>
function jsonp_callback(data) {
console.log(data.name);
// cannot access $scope here :(
}
</script>
Hmm you are using $http so I guess angular is generally available.
Is there a way to access $scope in my callback?
If the script block is within the same document, then any scope is accessible by doing i.e. angular.element('body').scope().
<script>
function jsonp_callback(data) {
console.log(data.name);
// access $scope here :)
var scope = angular.element('body').scope();
scope.$apply(function() {
scope.lastResult = data;
});
}
</script>
Element body is used only as an example. It might be adapted for any DOM element related to the target scope.
You shouldn't have to write the callback function yourself. It should be enough to use the special "success" method from the resulting promise from the $http.jsonp call. If the following code is in the controller, you should still have access to the $scope variable.
$http.jsonp(url).
success(function(data, status, headers, config) {
// The data is here
}).
Edit I've realised this answer depends on there being a string JSON_CALLBACK in the url passed to $http.jsonp, which I suspect Angular replaces with some unique callback function it's defined. The server must then interpret this, and output JSON wrapped in a call to this function. This might not work on S3, which just serves static files.
Use the $q promise library to pass the data back to the scope
In the director.js
function eventReturn($http, $q){
return {
getEvent: function(){
var deferred = $q.defer();
$http({method:'GET', url'http://my_s3_url/abc/v1/klm/my.json'}).
success(function(data, status, headers, config){
deferred.resolve(data);
});
return deferred.promise;
}
}
};
and in the controller.js
$scope.event = eventReturn.getEvent();
I have created the plunker for your scenario, its like when page loads it will read the json file from $http and then call the external js file function,to that function it will pass the $scope and result data, that external function take the result and display by using scope.
url : http://plnkr.co/edit/k66KevvcIyxiKA5QSBAc?p=preview
hope this is what ur looking.
I use the AWS javascript lib and had to use apply:
AWS.config.update({accessKeyId: '?', secretAccessKey: '?'});
var s3 = new AWS.S3({ maxRetries: 5});
console.log("S3 correctly configured");
s3.listObjects( {Bucket : 'bucketName', Prefix : 'foo/bar/' }, function (err, data) {
if (err) {
console.log(err); // an error occurred
} else {
console.log(data); // successful response
sc.$apply(function() {
sc.prefix = data.Prefix;
sc.data = data;
});
}
});

Categories