I was looking to use a weather API (like yahoo's) and make my javascript code able to return the temperature given a city.
My app runs on rivescript (built on javascript and node).
Researching I only found ways to do it locally on json, or by using html and css as well, but I just want a simple javascript code that returns a value with the temperature.
Thanks
You can try something like this, using openweathermap.org APIs:
function getWeather(city, callback) {
var url = 'http://api.openweathermap.org/data/2.5/weather';
$.ajax({
dataType: "jsonp",
url: url,
jsonCallback: 'jsonp',
data: { q: city },
cache: false,
success: function (data) {
callback(data.main.temp);
}
});
}
This example uses a name of a city as input, and returns temperature in K° degrees.
The data.main.temp value is returned, but you could return just data to have the whole weather object for that city.
Otherwise, if you want to use Yahoo Weather API (with your APPID):
function getWeather(position, callback) {
var lat = position.coords.latitude;
var lon = position.coords.longitude;
// Yahoo's PlaceFinder API http://developer.yahoo.com/geo/placefinder/
// We are passing the R gflag for reverse geocoding (coordinates to place name)
var geoAPI = 'http://where.yahooapis.com/geocode?location='+lat+','+lon+'&flags=J&gflags=R&appid='+APPID;
// Forming the query for Yahoo's weather forecasting API with YQL
// http://developer.yahoo.com/weather/
var wsql = 'select * from weather.forecast where woeid=WID and u="'+DEG+'"',
weatherYQL = 'http://query.yahooapis.com/v1/public/yql?q='+encodeURIComponent(wsql)+'&format=json&callback=?', code, city, results, woeid;
// Issue a cross-domain AJAX request (CORS) to the GEO service (not supported in Opera and IE)
$.getJSON(geoAPI, function(r) {
if (r.ResultSet.Found == 1) {
results = r.ResultSet.Results;
city = results[0].city;
code = results[0].statecode || results[0].countrycode;
woeid = results[0].woeid; // the the city identifier for the weather API
// Make a weather API request (it is JSONP, so CORS is not an issue):
$.getJSON(weatherYQL.replace('WID', woeid), function(r) {
if (r.query.count == 1) {
var item = r.query.results.channel.item.condition;
callback(item.temp
} else {
console.error("Error retrieving weather data!");
}
});
}
}).error(function(){
console.error("Sorry, your browser does not support CORS requests!");
});
}
This example uses a position as input (see navigator.geolocation), and returns temperature in C° degrees.
Note:
- both examples imply the use of jQuery.
- the second example implies having obtained a Yahoo APPID
Related
I am going to make a web app that show local weather using openweathermap api.
When I click the button, an IP API was called to get the co-ordinate of my location(longitude and latitude). These information then was used with API key (I registered in the website openweathermap.org) to create URL to call weather info according to the APIdocs, then change the HTML element with the data got from the server. I doing this on codepen. I tried to do the simplest one but it doesn't work.
<h1>weather forcast</h1>
<button id="btn">view</button>
<p id ="test">change me</p>
<p id ="place">place</p>
<p id ="temp">temperature</p>
<p id ="description">description</p>
var getLocation = function(data) {
var lat = data.lat;
var lon = data.lon;
var apiKey = "[APIKEY]";
};
var url = 'http://api.openweathermap.org/data/2.5/weather?' + 'lat=' + lat + '&lon=' + lon + '&appid=' + apiKey;
//call back function to extract weather info.
var getWeather = function(data) {
var temp = data.main.temp;
var description = data.weather[0].description;
var place = data.name;
};
$(document).ready(function() {
$("#btn").click(function() {
$.getJSON('http://ip-api.com/json', getLocation, 'jsonp')
$.getJSON(url, getWeather, 'jsonp');
$("#test").text("I AM CHANGED. THANKS!")
$("#temp").text(temp)
$("#description").text(description)
$("#place").text(place)
})
})
You have several issues. The first is that the $.getJSON calls are asynchronous, so the text() of the elements will be changed before any request completes. You need to place all code dependant on the values returned from the request in the callback functions.
Secondly you have issues with variable scope where you're defining your variables inside the function and then attempting to use them outside where they will be undefined.
With that said, you need to re-arrange your logic to something like this:
var getWeather = function(data) {
$.getJSON('http://api.openweathermap.org/data/2.5/weather', {
lat: data.lat,
lon: data.lon,
appid: "[APIKEY HERE]"
}, showWeather, 'jsonp');
};
var showWeather = function(data) {
$("#test").text("I AM CHANGED. THANKS!")
$("#temp").text(data.main.temp)
$("#description").text(data.weather[0].description)
$("#place").text(data.name)
};
$(document).ready(function() {
$("#btn").click(function() {
$.getJSON('http://ip-api.com/json', getWeather)
})
})
Note that the function calls are chained from the event (ie the click makes the location AJAX request, which calls getWeather which then calls showWeather. Also note how the variables are now local and used within their own function scope.
Finally, check that you're using the correct data formats for the AJAX requests. ip-api.com/json is returning JSON, not JSONP.
You can get data about the location with use third-party API. for example:http://ip-api.com/.
You get your location weather data from OpenWeatherMap service using the ip-api. its help you to get visitor location weather.
var getIP = 'http://ip-api.com/json/';
var openWeatherMap = 'http://api.openweathermap.org/data/2.5/weather'
$.getJSON(getIP).done(function(location) {
$.getJSON(openWeatherMap, {
lat: location.lat,
lon: location.lon,
units: 'metric',
APPID: 'Your-Openweather-Apikey'
}).done(function(weather) {
$('#weather').append(weather.main.temp);
console.log(weather);
})
})
I am trying to use the Forecast.io weather API to build a weather application with Ionic. I am having a hell of a time getting the AJAX response data delivered to my controller for use in my view.
My Factory Service:
.factory('WeatherService', function($cordovaGeolocation) {
var posOptions = { timeout: 10000, enableHighAccuracy: false };
return {
// Get current Geolocation position with the configured /posOptions/
getPosition : $cordovaGeolocation.getCurrentPosition(posOptions),
// Query the result of /getPosition/ for /lat/, /long/, and /accuracy/
getCoords : function(pos) {
var loc = {
lat : pos.coords.latitude,
long : pos.coords.longitude,
accuracy : pos.coords.accuracy
};
return loc;
},
// Build the API request URI
getApi : function(lat, long) {
var url = 'https://api.forecast.io/forecast/';
var apiKey = 'foo';
var forecastApi = url + apiKey + '/' + lat + ',' + long + '?callback=?';
return forecastApi;
},
// Execute a request against the API URI to recieve forecast data
getForecast : function(api) {
var forecast;
$.ajax({
url : api,
dataType : 'json',
async : false,
success : function(res) {
forecast = res;
}
});
return forecast;
}
};
})
My Controller Method:
.controller('DashCtrl', function($scope, WeatherService) {
WeatherService.getPosition.then(function(pos) {
var pos = pos;
return pos;
}).then(function(pos) {
var coords = WeatherService.getCoords(pos);
return coords;
}).then(function(coords) {
var api = WeatherService.getApi(coords.lat, coords.long);
return api;
}).then(function(api) {
$scope.forecast = WeatherService.getForecast(api);
console.log($scope.forecast);
});
})
There's probably a lot of things inherently wrong with the above code. From my reading I have been made aware that then() methods really shouldn't be used in the controller method, and all of that logic should be isolated to the Service Method. I will be refactoring to that pattern when I get this working.
I am using the jQuery $.ajax() instead of $http because of CORS issues with Forecast.io when developing locally. $jsonp was throwing syntax errors on the response, so I had to resort to jQuery for the call to get this working locally.
I know I am getting a successful response because if I console.log(forecast) inside the $.ajax call I can explore the weather data. For whatever reason, I am unable to save the response value to the forecast var saved in the parent scope of the ajax call and then return that to the controller for use in my view with the $scope.forecast variable. It is always returning undefined.
I have looked at plenty of SO questions while trying to get this working on my own, and have yet to have any success..
How do I return the response from an asynchronous call?
Get Data from a callback and save it to a variable in AngularJS
Well, if you really really feel the need to use ajax (probably better to track down and fix the jsonp issue) then you should probably wrap the forcast in your very own promise.
.factory('WeatherService', function($q,$cordovaGeolocation) {
...
getForecast : function(api)
{
var deferred = $q.defer();
$.ajax({url : api, dataType : 'json', async : false,
success : function(res) {
defereed.resolve(res);
}
});
return defereed.promise;
}
You already know how to handle promises in your controller code so I won't post those changes.
I am struggling with this issue for 2 days...
I have a JavaScript array (20,000K rows and 41 columns). It was originally received in javaScript through an ajax call as shown below,
var dataArray = [];
var dataRequest = {};
dataRequest.SearchCondition = 'some value';
$.ajax({
type: "POST",
url: "api/GetData/ProcessRequest",
dataType: 'json',
cache: false,
async: true,
crossDomain: false,
data: dataRequest ,
success: function (response) {
dataArray = response;
},
error: function (xhr, textStatus, errorThrown) {
dataArray = null;
}
});
In the application, the user will verify the data and send it back to Web API method.
I am trying to send the same data back (dataArray) to web api method but, it fails. Please see the code below,
Option 1: (failed - the request did not hit web api method)
var dataArrayJsonStr = JSON.stringify(dataArray);
$.ajax({
type: "POST",
url: "api/SendData/ProcessRequest",
dataType: 'json',
data: {'dataValue':dataArrayJsonStr },
success: function (response) {
alert('success');
},
error: function (xhr, textStatus, errorThrown) {
alert(errorThrown)
}
});
In IE 8, I am getting 'out of memory' exception popup. (most of our application users still have IE 8)
In Chrome, it crashes.
Option 2 tried: (don't know how to read the value)
I tried to send the same value to web api through XmllHttpRequest
var dataArrayJsonStr = JSON.stringify(dataArr);
var xmlRequest;
if (window.XMLHttpRequest) {
xmlRequest = new XMLHttpRequest();
}
xmlRequest.open("POST", "api/SendData/ProcessRequest", false);
xmlRequest.setRequestHeader('Content-Type', 'application/text');
xmlRequest.send("dataValue=" + dataArrayJsonStr);
Using Chrome, I am able to post the data successfully to Web API, I am seeing the content-length as '128180309'. But, I don't see the values. How do i get the values in Web API?
Please suggest me how to send large data back to web api from javascript.
Thanks,
Vim
I think you create overhead, maybe I wrong, you can edit me.
Did you really need send back all datas back or you just need send modified data?
Because in real life hard to imagine that user will review 20.000 of rows.
Good example is ExtJS stores, you can see example here
Key thing of stores that they send back to the server only modified or deleted data, it save browser, network and server resources.
Try to add more memory for API or more time excecution, also you can try return data in more small parts. Defining the number of parts to send.
Did you try to send the data by chunks?
I mean, you need to split it in small pieces and perform multiple number of requests.
For example, it can be like:
--HELLO SERVER. STARTING TRANSMITION FOR DATA SET #177151--
PIECE 1/13
PIECE 2/13
...
PIECE 13/13
--BUE SERVER--
So, it will take some time, but you can send any amounts of data without memory problems. If you're struggling with it for 2 days, I think you got some time to code it :)
UPD1: Client code example.
Here's an example of client code. This is a simple chunking algorithm.
Have to say I didn't test it, because it would take a lot of time to represent your situation.
So, you should read it and get the point.
You have a simple function, that takes you whole data set and callbacks for each response (to update your progress bar, e.g.), for successful finish and for error.
Hope, it will help you to make some problems.
Also, I can help you to build architecture on the server-side, but I need to know what technologies do you use.
function sendData(data, onEach, onFinish, onError) {
var CHUNK_SIZE = 1000;
var isFailed = false;
var chunkNum = 0;
var chunk, chunkStart, chunkEnd;
while(data.length + CHUNK_SIZE > chunkNum * CHUNK_SIZE) {
if(isFailed) {
return;
}
chunkStart = chunkNum * CHUNK_SIZE;
chunkEnd = chunkStart + CHUNK_SIZE + 1;
chunk = {
num: chunkNum,
data: data.slice(chunkStart, chunkEnd)
};
ajaxCall(chunk);
chunkNum++;
}
function ajaxCall(data) {
$.ajax({
type: "POST",
url: "api/GetData/ProcessRequest",
dataType: 'json',
async: true,
data: dataRequest ,
success: function (response) {
onEach(data, response);
},
error: function (xhr, textStatus, errorThrown) {
isFailed = true;
onError(arguments);
}
});
}
}
I need to create a simple web site that gets the stock value based on the ticket.
Input: CSCO Output: 23.49. I'm very new to both webservices and javascript. The current YQL statement I am using is: select * from yahoo.finance.quotes where symbol="CSCO" which does not work.
function getprice()
{
var symbol = $('#stockquote').val();
var url = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22"+symbol+"%22)%0A%09%09&env=http%3A%2F%2Fdatatables.org%2Falltables.env&format=json";
$.getJSON(url, function (json)
{
var lastquote = json.query.results.quote.LastTradePriceOnly;
$('#stock').text(lastquote);
});
}
I'm retrieving the elevation data from the Google Maps API by AJAX.
I'm getting the data back I want as if I look at the console in Chrome I can see a 200 status code and can see the data in the response tab. But is throws up 'Uncaught SyntaxError: Unexpected token :' so I can't display anything from the JSON file.
This is my code:
var theURL = 'http://maps.googleapis.com/maps/api/elevation/json?locations=' + longitude + ',' + latitude + '&sensor=false&callback=?';
$.ajax({
url: theURL,
type: 'get',
dataType: 'json',
cache: false,
crossDomain: true,
success: function (data) {
var theData = $.parseJSON(data);
console.log(theData);
}
});
The live code is here: http://map.colouringcode.com/
All help is greatly appreciated.
The Google Maps API does not support direct JSONP requests.
Instead, you need to use the Javascript API.
Realizing this question is well outdated, I hope that this might be able to help someone in the future. This was my first encounter with javascript and especially all this JSON stuff and therefore caused a lot of hitting my head off the desk trying to figure out what I was doing wrong.
Here is my solution that retrieves the clients location (in lat and lng) and then uses the google geocoding api to determine their location in "human readable" format.
function currentLocation() {
navigator.geolocation.getCurrentPosition(foundLocation, errorLocation);
function foundLocation(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
//This is where the geocoding starts
var locationURL= "http://maps.googleapis.com/maps/api/geocode/json?latlng="
+ lat + "," + lng + "&sensor=false&callback=myLocation"
//This line allows us to get the return object in a JSON
//instead of a JSONP object and therefore solving our problem
$.getJSON(locationURL, myLocation);
}
function errorLocation() {
alert("Error finding your location.");
}
}
function myLocation(locationReturned) {
var town = locationReturned.results[0].address_components[1].short_name;
var state = locationReturned.results[0].address_components[4].short_name;
console.log(town, state);
}