AngularJS: Using $http.get to retrieve data and making it available - javascript

I am very new to AngularJS and want to get started retrieving data from a remote source.
My app.js file looks like this:
var app = angular.module('footy', []);
app.controller('ClubController', ['$http', function($http){
var club = this;
club.team = [];
$http.get('http://api.football-data.org/teams/19').success(function(data){
club.team = data;
});
}]);
and my html looks like this:
<!doctype html>
<html ng-app="footy">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller = "ClubController as data">
{{data.club.team.name}}
</div>
</body>
</html>
When I view the page in a browser all that is returned is a blank page and in the source I can see "{{data.club.team.name}}" between the div.
When I view the data source Url in a browser I see this:
{
"id": 19,
"name": "Eintracht Frankfurt",
"shortName": "Eintr. Frankfurt",
"crestUrl": "http://upload.wikimedia.org/wikipedia/commons/0/04/Eintracht_Frankfurt_Logo.svg"
}
I have gone through and completed this course: http://campus.codeschool.com/courses/shaping-up-with-angular-js/ and was trying to apply the instructions from chapter 5 about services to this but I am having no luck.
Can someone help? Thanks in advance.

I see two problems here:
http://api.football-data.org/teams/19 doesn't allow CORS. You can't load the data. Update: The OP pointed out that s/he has an API key that allows CORS. This is not the issue then, but might be for other people trying to reproduce this.
{{data.club.team.name}} should be {{data.team.name}} because you said var club = this;. In other words, the controller you aliased data is the same as the club object. The club object is not a property of the controller data, it IS the controller's data.
See this plnkr for a demo. The commented out code doesn't work because of the api key, the locally hosted file does: http://plnkr.co/edit/ItD96Zfk0g1cLyGrrgBy?p=preview

Related

RESTful API not showing up with simple AngularJS controller

Alright, I'll try and explain this as simply as possible. I have setup a Node and express and mySQL server running a RESTful API with the common get, post, put, delete working fine as I can test them with them in Postman and just looking it up in Chrome. This is all run locally on my machines for now. I have a Ubuntu box running the REST api. When I just query in chrome I get an expected output of the fields I am working with.
(Example request "http://192.168.239.130:1337/api/plates/") Gives me this.
{
"Plates": [
{
"lot_number": "P234",
"plate_number": "NGE-781",
"date_and_time": "2016-07-08T21:14:31.000Z"
},
{
"lot_number": "P234",
"plate_number": "FEB-423",
"date_and_time": "2016-07-08T21:26:08.000Z"
},
{
"lot_number": "P234",
"plate_number": "SEB-623",
"date_and_time": "2016-07-08T21:26:20.000Z"
},
{
"lot_number": "P234",
"plate_number": "ZEB-683",
"date_and_time": "2016-07-08T21:30:59.000Z"
},
{
"lot_number": "P234",
"plate_number": "FEW-083",
"date_and_time": "2016-07-08T21:31:57.000Z"
},
{
"lot_number": "L323",
"plate_number": "JEQ-324",
"date_and_time": "2016-07-11T18:59:03.000Z"
}
]
}
These are just some sample mySQL data that is printed to screen. Which is working as I had hoped. My problem is when I try to make a simple html page with angular script to try and print it it doesn't want to. All I get is a blank page. I have tried running my code with other api's online. I have no problem printing those out with the identical code which I will post below.
<!DOCTYPE html>
<html>
</style>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="platesCtrl">
{{plates}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('platesCtrl', function($scope, $http) {
$http.get("http://192.168.239.130:1337/api/plates")
.then(function (response) {$scope.plates = response.data;});
});
</script>
</body>
</html>
Like I said running this with any other API online works.... Mine doesn't It it something that has to do with it be local? Even though like I stated I can run the above address to the ....api/plates API in a browser no problem and get the JSON to spit out.
Any knowledge would be appreciated
Thanks.
Alright, I'll answer this myself. Thought from the comments given from a few other users. I checked the console and was given an error that states that I have a cross domain issue and that 'Access-control-Allow-Origin' missing. I was able to fix be going into my API calling functions and add
res.header("Access-Control-Allow-Origin", "*");
to every API call. For now this works though I am sure there is a more elegant way to implement the same thing.
Thanks for the help.

AngularJS accessing a JSON file within a ng-repeat

Is something like this possible in Angular, I have tried searching but I don't know the exact terms to search for, so first of all, my apologies.
I am using Angular successfully to access a JSON file.
My JSON file contains a list of over 150 events, each event has some basic information like image, title, price, whether the event is sold out etc.
Each event ALSO contains a URL to JSON file about that event.
This file contains much more in depth information about the individual event such as location, difficulty, wheelchair accessible etc.
How can I loop through the first JSON but still extract the information for the "embedded"? JSON file so that I display all information on one page.
I am stuck with being able to understand how to "call" that second JSON file of information while being in a ng-repeat.
and as a beginner to Angular I struggled to search for the correct terminology to help myself.
thanks
EDITED -----
I have created a plunkr here of part of what I am trying to achieve.
http://plnkr.co/edit/zYAhNKdM18pxuK5roPjj?p=preview
<!DOCTYPE html>
<html>
<head>
<style>
#event-list span{display:block;}
#event-list li{clear:both;}
#event-list ul{list-style: none;}
#event-list img{float:left;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
var app = angular.module("exampleApp", []);
app.controller("eventCtrl", function ($scope, $http, $location) {
var eventList = "http://ajax.wiggle.co.uk/api/list/events/?ris=1";
$scope.host = $location.host;
$scope.wiggleEvents = [];
$http({
method: 'JSONP',
url: eventList + '&callback=JSON_CALLBACK'
}).success(function (data, status, headers, config) {
$scope.wiggleEvents = data.Results.Products;
// data contains the response
// status is the HTTP status
// headers is the header getter function
// config is the object that was used to create the HTTP request
}).error(function (data, status, headers, config) {
});
});
</script>
</head>
<body ng-app="exampleApp">
<div ng-controller="eventCtrl">
<div class="row">
<div class="col-md-12" id="event-list">
<ul>
<li ng-repeat="p in wiggleEvents" >
<!-- i need to display a mixture of information from the first JSON file and information from each individual events JSON file -->
<img src="" ng-src="{{p.Image}}?w=125&h=125&a=7" />
<span class='name'>Title: {{p.Title}}</span>
<span>PID: {{p.pid}}</span>
<!--Each of these events has an Apirl which is a JSON file of the information on the event -->
<span>ApiUrl: {{p.ApiUrl}}</span>
<!--AND here i want to add short description of each event. found in the API of each individual event -->
<!--AND here i want to add difficulty rating from API of each individual event -->
<!--AND here i want to add location area of each individual event etc etc etc -->
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
I can successfully get information from the main JSON file, and display the 24 events in the page.
the main JSON file is here:
http://ajax.wiggle.co.uk/api/list/events/?ris=1
each "product" in that JSON has it's own APIUrl to it's own individual JSON file which contains more information about that individual product.
I am trying to output in my html some information from the main JSON and some information from each idividual JSON at the same time.
I am really stuck with how to access each of those individual JSON files, especially as there could be varying amount of "products" contained within the first main file. it happens to be 24 today, but it could be 36 tomorrow etc.
thanks
let's say you have the following json object:
myJsonObj= {
user: {
firstname : "jane",
lastname : "doe"
},
friend: {
firstname: "hancock",
lastname : "john"
}
}
To iterate over properties an object litteral (your json object) using ng-repeat, you must use (key, value) like:
<div ng-repeat="(key,value) in myJsonObj">
<span ng-bind="key"></span> // displays "user" , then "friend"
<span ng-bind="value.firstname"></span> // displays "jane"
<span ng-bind="value.lastname"></span> // displays doe
</div>
read more about iterating over object properties here : ng-repeat .
Edit:
you can also do more stuff by passing some data to a scope function. like
<div ng-repeat="(key,value) in myJsonObj">
// assuming retrieveUrl() is a scope function you wrote
// in order to extract and return the url from the data you passed
// as parameter
<span ng-bind="retrieveUrl(value.url)"></span>
</div>
The best way to fetch json data from a url in the data nested within an ng-repeat would be to write a directive that runs a $http GET. Something like this:
http://plnkr.co/edit/xFCG1p8WwDw9bt6jO49q?p=preview
html
<div ng-repeat="thing in things track by $index">
<get-url-data url="thing"></get-url-data>
</div>
js:
app.directive('getUrlData', function() {
return {
restrict: 'E',
template: '<div>{{vm.jsonData}}</div>',
scope: {
url: '=?'
},
controllerAs: 'vm',
bindToController: true,
controller: function($http) {
vm = this;
$http.get(vm.url).then(function(response) {
vm.jsonData = response;
});
}
};
});
I managed to find an answer for this question.
I followed the chosen answer in this stackoverflow post:
How to bind multiple JSON files in ng-repeat (AngularJS)?
This was written in a way I understood, and it worked for me when I followed it.

Angular and JSON interaction?

I'm trying to implement a very basic system involving angular.js and JSON, but I can't get it to behave. All I want to do is get the value for a particular field in my JSON file and spit it onto the page. Can anyone see why this isn't working? It finds the database every time, but I can't seem to access the object.
HTML & JS
<html lang="en" ng-app="ngApp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.min.js"></script>
<script>
var ngApp = angular.module('ngApp', []);
ngApp.controller('ngCtrl', function($scope, $http){
$http.get("db.json").success(function(data){
console.log("Database found");
$scope.data = data;
});
});
</script>
<body ng-controller="ngCtrl">
<div>Data goes here: {{data.field1}}</div>
</body>
</html>
JSON
[
{
"field1":"data1",
"field2":"data2"
}
]
I'm very new to angular, so I wouldn't be surprised if there's something I missed.
Your json response is array of objects. So, you've to use array notation to access the data from it.
See the highlighted changes below:
<div>Data goes here: {{data[0].field1}}</div>
// ^^^
You might want to use ng-repeat to loop over all the data
<body ng-controller="ngCtrl">
<div ng-repeat="item in data">
<span> Field1 : {{item.field1}}</span>
<span> Field2 : {{item.field2}}</span>
</div>
</body>
From first look it seems that json data returned is array of an objects. Try this
data[0].field1

Issues with Google Visualization API on App Engine

I have been working on a front end to my App Engine app kind of based on this codelab. I have a text box where you enter in a stock ticker symbol (like say, AMZN or GOOG), which it uses as criteria to run a query to Google BigQuery in the background and then it's supposed display the tweet count over several days in a Google Visualization API line chart.
But, based on what I've seen in the source code from the page, it's not pulling the query results from BigQuery into the data template variable {{ data }}. Here's my HTML code (called index1.html), which for the most part is like the codelab's:
<!--
You are free to copy and use this sample in accordance with the terms of the
Apache license (http://www.apache.org/licenses/LICENSE-2.0.html)
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>
Jibdan Analytics
</title>
<script type="text/javascript" src="//www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', {packages: ['corechart']});
</script>
<script type="text/javascript">
countdata = {{ data }}
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.DataTable(query_response);
// Create and draw the visualization.
var chart = new google.visualization.LineChart(document.getElementById('visualization'));
chart.draw(data, {title: "Tweets by Day by Ticker",
curveType: "function",
width: 800, height: 600}
);
}
google.setOnLoadCallback(drawVisualization);
</script>
</head>
<body style="font-family: Arial;border: 0 none;">
<div id="visualization" style="width: 800px; height: 640px;"></div>
</body>
</html>
I messed with the html and Javascript after looking at the Google Code Playground code for the line chart, but really it seems like the issue is with that template variable.
Here's the pertinent Python code, too. The first method is supposed to take the BigQuery response and put it in a format that should be ingested by the Visualization API to produce a line chart. The get method has the query string to run and renders the results into the template, index1.html. Pretty much like the codelab:
class QueryHandler(webapp2.RequestHandler):
def _bq2line(self, bqdata):
logging.info(bqdata)
columnNameDate = bqdata['schema']['fields'][0]['name']
columnNameVal = bqdata['schema']['fields'][1]['name']
logging.info("Column Names=%s, %s" % (columnNameDate, columnNameVal))
countdata = { 'cols': ({'id':columnNameDate, 'label':columnNameDate, 'type':'string'},
{'id':columnNameVal, 'label':columnNameVal, 'type':'number'})}
countdata['rows'] = [];
logging.info(countdata)
for row in bqdata['rows']:
newrow = ({'c':[]})
newrow['c'].append({'v': row['f'][0]['v']})
newrow['c'].append({'v':row['f'][1]['v']})
countdata['rows'].append(newrow)
logging.info('FINAL COUNTDATA---')
logging.info(countdata)
self.response.out.write(countdata)
return json.dumps(countdata)
def get(self):
QUERY = """
SELECT STRFTIME_UTC_USEC(querydate, "%Y-%m-%d") AS tweet_date, COUNT(tweet_id) AS tweet_count
FROM [jibdantweetstream.tweetdata_09_21_2013]
WHERE gcs_load = true AND (REGEXP_MATCH(ticker, '""" + self.request.get('stock') + """'))
GROUP BY tweet_date
ORDER BY tweet_date
"""
try:
query_request = bigquery_service.jobs()
query = {'data': self._bq2line(bq.Query(QUERY, BILLING_ID)),
'query': QUERY}
query_response = query_request.query(projectId=BILLING_ID,
body=query).execute()
template = os.path.join(os.path.dirname(__file__), 'result1.html')
self.response.out.write(render(template, query_response))
finally:
self.response.out.write('Click here to go back to the Search page. ')
So, that's what I have. You'll see I have a couple of self.response.out.write statements in there, because I wanted to see if I was getting a response back with query results. I am getting results, so I know it's not an OAuth2 issue. I just don't know what else it could be.
Many Thanks in Advance.
"View Source", coupled with something (Firebug, Chrome Developer Tools) that'll tell you about syntax errors in your JavaScript are your friends. Looking at what you've provided, I'm guessing that expanding {{ data }} will result in a syntax error. And as asgallant noted, you're setting up countdata but referencing query_response instead.
Since your data is a date and a count, you're not going to run into entity escaping issues, but if you expand the query to include something else, you'll run into the problem of {{ data }} being escaped for HTML, where it needs to be escaping for JS. To handle that, you'll need the escapejs filter.
In your code:
countdata = { 'cols': ({'id':columnNameDate, 'label':columnNameDate, 'type':'string'},
{'id':columnNameVal, 'label':columnNameVal, 'type':'number'})}
It should be:
countdata = { 'cols': [{'id':columnNameDate, 'label':columnNameDate, 'type':'string'},
{'id':columnNameVal, 'label':columnNameVal, 'type':'number'}]}

How to connect and put in JSON instead of mongolab in AngularJS?

I want to use JSON instead of MongoLab example shown on AngularJS website.
Here's the code from the website:
angular.module('mongolab', ['ngResource']).
factory('Project', function($resource) {
var Project = $resource('https://api.mongolab.com/api/1/databases' +
'/angularjs/collections/projects/:id',
{ apiKey: '4f847ad3e4b08a2eed5f3b54' }, {
update: { method: 'PUT' }
}
);
Is there any way I could connect and put into JSON file available on my folder instead of hosting it to MongoLab?
Any response would be really appreciated!
You can look at this example:
Reading in JSON through Angular Resources Service
You want to return the Project variable from your factory
var Project = $resource('test.json', {} );
return Project;
then use it in the controller after you inject it:
Project.get(function(data){
$scope.bar = data.foo;
});
Update:
After looking thru the 1.1.3 angular-resource.js code, it looks like it always does an http request to get its data. Set up a simple RoR app with a REST interface for testing.
Or use plunker (like the linked question above) for complete remote testing.

Categories

Resources