I'm using geolocation to get my own latitude and longitude,but the console always return undefined,btw when I clicking the tiy geolocation toturial on w3chool the response is "Location information is unavailable".
var lati,lgi;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error);
} else {
console.warn("Your browser don't support geoloction!");
}
function success(pos) {
console.log(pos);
var cr;
cr = pos.coords;
lati= cr.latitude;
lgi = cr.longitude;
console.log(lati+","+lgi);
}
function error(err) {
console.warn("ERROR(" + err.code + "): " + err.message);
}
updated:I use dark-sky api to get some weather JSON,the remaining code updated.
function getData() {
var userkey = "***my key***";
var site = "https://crossorigin.me/https://api.darksky.net/forecast/";
var reqstr = site + userkey + lati + "," + lgi;
console.log(reqstr);
var data;
$.getJSON(reqstr, function(result) {
data = JSON.parse(result);
});
console.log(data.latitude);
}
getData();
Related
I am creating a project that displays the current weather of an area by name search. I fetch the API data from open weather: https://openweathermap.org/current?fbclid=IwAR1SVc9zn9uXaZWLmJA9lYEeZvUc1s_kR68RFadWuIwd8yBjIyJ7zsVMKkE
I have added all the parametres of the API to my code, but if you search some areas, they don't "return" all the weather API parameters. For example, when I search my city's weather at the moment, the parameter " Atmospheric pressure on the sea level" is displaying "undefined" because as Open Weather stated:
Because of that, I don't want the final project to display:
Atmospheric pressure on the sea level: undefined
I want it to return something among the lines of:
Atmospheric pressure on the sea level: not found
As you can see, the data type undefined is replaced with a string.
However, I have found a function here on this site that replaces undefined with "0" and it seems to work because it is marked as "solution". Due to my lack of knowledge tho, I cant get it to work.
The code I have found:
function replaceUndefined(displayWeather){
if(typeof(displayWeather) === "undefined"){
return "0"; // return 0 as replace, and end function execution
}
return displayWeather; // if the above state is false, functions continues and return original value
};
Now, here is my whole JAVASCRIPT code:
let weather = {
apiKey: "χχχχχχχχχχχχχχχ",
fetchWeather: function (city) {
fetch(
"https://api.openweathermap.org/data/2.5/weather?q=" +
city +
"&units=metric&lang=el&appid=" +
this.apiKey
)
.then((response) => {
if (!response.ok) {
alert("No weather found.");
throw new Error("No weather found.");
}
return response.json();
})
.then((data) => this.displayWeather(data));
},
displayWeather: function (data) {
const { name } = data;
const { lon } = data.coord;
const { lat } = data.coord;
const { icon, description } = data.weather[0];
const { temp, humidity } = data.main;
const {temp_min} = data.main;
const {temp_max} = data.main;
const { pressure } = data.main;
const { sea_level } = data.main;
const { speed } = data.wind;
const { deg } = data.wind;
const { sunrise } = data.sys;
const { sunset } = data.sys;
//getting the data from the JSON API file.
document.querySelector(".city").innerText = "Καιρός: " + name;
// (".city") is the class name from the DIV in HTML file.
document.querySelector(".lon").innerText = "Γεωγραφικό μήκος (longitude): " + lon;
document.querySelector(".lat").innerText = "Γεωγραφικό πλάτος (latitude): " + lat;
document.querySelector(".icon").src =
"https://openweathermap.org/img/wn/" + icon + ".png";
document.querySelector(".description").innerText = description;
document.querySelector(".temp").innerText = temp + "°C";
document.querySelector(".temp_min").innerText = "Ελάχιστη θερμοκρασία (αυτην την στιγμή): " + temp_min + "°C";
document.querySelector(".temp_max").innerText = "Μέγιστη θερμοκρασία (αυτην την στιγμή): " + temp_max + "°C";
document.querySelector(".humidity").innerText =
"Υγρασία: " + humidity + "%";
document.querySelector(".pressure").innerText = "Πιέση: " + pressure;
document.querySelector(".sea-pressure").innerText = "Ατμοσφαιρική πίεση στο επίπεδο της θάλασσας: " + sea_level;
document.querySelector(".wind").innerText =
"Ταχύτητα αέρα: " + speed + " km/h";
document.querySelector(".wind-deg").innerText = "Κατεύθυνση του αέρα (degrees): " + deg;
document.querySelector(".sunrise").innerText = "Ανατολή Ήλιου: " + window.moment(sunrise * 1000).format('HH:mm a');
document.querySelector(".sunset").innerText = "Δύση Ήλιου: " + window.moment(sunset * 1000).format('HH:mm a');
document.querySelector(".weather").classList.remove("loading");
document.body.style.backgroundImage =
"url('https://source.unsplash.com/1600x900/?')";
},
search: function () {
this.fetchWeather(document.querySelector(".search-bar").value);
},
};
document.querySelector(".search button").addEventListener("click", function () {
weather.search();
});
document
.querySelector(".search-bar")
.addEventListener("keyup", function (event) {
if (event.key == "Enter") {
weather.search();
}
});
weather.fetchWeather("London");
//Loads weather of London when the page opens
(some texts in the code are in greek because I want the text that is displayed on the page, to be in that language)
Thank you. Please I need solution.
document.querySelector(".sea-pressure").innerText = "Ατμοσφαιρική πίεση στο επίπεδο της θάλασσας: " + sea_level || 'not found';
Or just for hide all the line if data doesn't exist
if(seal_level){
document.querySelector(".sea-pressure").innerText = "Ατμοσφαιρική πίεση στο επίπεδο της θάλασσας: " + sea_level;
}
My goal is to wrap MySQL queries, pass the parameters to a function and another function does the MySQL job, returning the results.
Here's my code so far:
//mysql lib
var mysql = require('mysql');
//database credentials
exports.pool = mysql.createPool({
connectionLimit: 50,
host: 'localhost',
user: 'root',
password: 'password',
database: '_app',
debug: false
});
//my wrapper =(
var returnResultset = exports.returnResultset = function (qry) {
return new Promise(function (resolve, reject) {
try {
mysql_.pool.getConnection(function (err, connection) {
if (err) {
console.log("Error on function returnResultset - MYSQL ERROR: " + err);
return reject(err);
}
connection.query(qry, [], function (error, results, fields) {
connection.release();
if (error) {
console.log("Error on function returnResultset - MYSQL ERROR: " + error);
return reject(error);
}
return resolve(results);
});
});
}
catch (e) {
console.log('error:' + e);
}
});
};
//wrapper function for testing purposes
var selectOneField = exports.selectOneField = function (tbl, field, pk, pkval) {
var qry_ = "SELECT " + field + " FROM " + tbl + " WHERE " + pk + " = '" + pkval + "'";
returnResultset(qry_).then(function (results) {
return results;
}, function (error) {
console.log("Error: " + error);
})
};
//...and on another page I want to be able to receive the results from the function above:
var isExpired = exports.isExpired = function (cod) {
var rtf = db_.selectOneField('view_expiredusers', 'cod', 'cod', cod);
console.log(rtf);
return rtf;
};
The code above returns undefined. I can't get to make this function working properly.
I have tried console.log(results). The query works like a charm. Only thing I can't get to work is to catch the result from an external function.
Any thoughts? Thanks in advance!
You should return the promise and chain it inside isExpired function.
//wrapper function for testing purposes
var selectOneField = exports.selectOneField = function (tbl, field, pk, pkval) {
var qry_ = "SELECT " + field + " FROM " + tbl + " WHERE " + pk + " = '" + pkval + "'";
return returnResultset(qry_);
};
//...and on another page I want to be able to receive the results from the function above:
var isExpired = exports.isExpired = function (cod) {
return db_.selectOneField('view_expiredusers', 'cod', 'cod', cod)
};
When you call the isExpired in other files you should use the then method of the promise and return the results. do it as follows
var cod_customer = 1;
var isexpired;
isExpired(cod_customer).then(function (results) {
isexpired = results;
console.log(isexpired);
}, function (error) {
console.log("Error: " + error);
});
you are not returning the promise in selectOneField function it must return the promise and also you cant simply do
rtf = db_.selectOneField('view_expiredusers', 'cod', 'cod', cod);
.you will have to use async-await or then
Must be handled this way
//wrapper function for testing purposes
var selectOneField = exports.selectOneField = function (tbl, field, pk, pkval) {
var qry_ = "SELECT " + field + " FROM " + tbl + " WHERE " + pk + " = '" + pkval + "'";
return returnResultset(qry_).then(function (results) {
return results;
}).catch(error) {
console.log("Error: " + error);
})
};
//...and on another page I want to be able to receive the results from the function above:
var isExpired = exports.isExpired = function (cod) {
var rtf = db_.selectOneField('view_expiredusers', 'cod', 'cod', cod).then(rtf => {
console.log(rtf);
return rtf;
});
};
var latLon = "40.8,-77.8"; //Lat/lon
var cityCode = ""; //City code
var cityName = "";
var latLongCityCodeURL = ("http://dataservice.accuweather.com/locations/v1/cities/geoposition/search?apikey=" + weatherKey + "&q=" + latLon);
//Current Conditions Vars
var ccWeatherText = ""; //Text for weather at location
var ccTemp = 0; //Degrees Farenheit
var ccIcon = 0; //weather icon number https://developer.accuweather.com/weather-icons
var ccURL = "test"; //URL for get
//12 hour forecast Conditions Vars
//5 day forecast conditions Vars
//Get city code
http.get(latLongCityCodeURL, (resp) => {
var that = this;
resp.on("data", (chunk) => {
var result = JSON.parse(chunk);
var cityCode = result.Key;
var cityName = result.EnglishName;
console.log(cityCode + " " + cityName);
that.cityName = cityName;
that.cityCode = cityCode;
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
console.log(cityCode + " " + cityName);
So my issue is, I am making an http request using require('http'), what I want to do is parse the data and store it in my global variables so that I can use them for other requests. I have tried using var that=this and I have tried just assigning my global variables to the data. I am not sure how to do it, i just keep getting undefined. I know it has something to do with ASYNC and also something to do with the scope. Please help
You can save your result to a variable at various levels of scope.. just remember that most i/o calls in Node.js are asynchronous.
Here's an example:
var latLon = "40.8,-77.8"; //Lat/lon
var cityCode = ""; //City code
var cityName = "";
var latLongCityCodeURL = ("http://dataservice.accuweather.com/locations/v1/cities/geoposition/search?apikey=" + weatherKey + "&q=" + latLon);
//Current Conditions Vars
var ccWeatherText = ""; //Text for weather at location
var ccTemp = 0; //Degrees Farenheit
var ccIcon = 0; //weather icon number https://developer.accuweather.com/weather-icons
var ccURL = "test"; //URL for get
var savedResult = null;
//Get city code
http.get(latLongCityCodeURL, (resp) => {
var jsonData = '';
resp.on("data", (chunk) => {
jsonData += chunk;
});
resp.on("end", () => {
savedResult = JSON.parse(jsonData);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
// Display saved result once available.
setTimeout(displaySavedResult, 2000);
function displaySavedResult() {
if (!savedResult) {
console.log('Last result is null!');
} else {
console.log('Last result: City Code: ' + savedResult.Key + " Name" + savedResult.EnglishName);
console.log('Last result (all properties): ', JSON.stringify(savedResult, null, 2));
}
}
You can use Promise to make http request, here is code that may help you
const httpGet = url => {
return new Promise((resolve, reject) => {
http.get(url, res => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => {
try {
body = JSON.parse(body);
} catch (err) {
reject(new Error(err));
}
resolve({
cityCode: body.Key,
cityName: body.EnglishName
});
});
}).on('error', reject);
});
};
httpGet(latLongCityCodeURL).then(data => {
console.log(data.cityCode + " " + data.cityName);
}).catch(err => console.log('Got error ', err));
var latLon = "40.8,-77.8";
var latLongCityCodeURL = ("http://dataservice.accuweather.com/locations/v1/cities/geoposition/search?apikey=" + weatherKey + "&q=" + latLon);
//Current Conditions Vars
var ccWeatherText = ""; //Text for weather at location
var ccTemp = 0; //Degrees Farenheit
var ccIcon = 0; //weather icon number https://developer.accuweather.com/weather-icons
var ccURL = "test"; //URL for get
//12 hour forecast Conditions Vars
//5 day forecast conditions Vars
//Get city code
function getCityCode(latLongCityCodeURL){
return new Promise((resolve, reject) => {
http.get(latLongCityCodeURL, (resp) => {
resp.on("data", (chunk) => {
var result = JSON.parse(chunk);
var cityCode = result.Key;
var cityName = result.EnglishName;
resolve({cityCode, cityName});
});
}).on("error", (err) => {
reject(err);
console.log("Error: " + err.message);
});
})
}
getCityCode(latLongCityCodeURL)
.then((result) => {
console.log(result.cityCode, result.cityName)
}).catch((err) => console.log(err))
Another way is to use async-await API interface which is supported in node 8.
async function getCityCode(latLongCityCodeURL){
const result = await http.get(latLongCityCodeURL, (resp) => {
resp.on("data", (chunk) => {
var result = JSON.parse(chunk);
var cityCode = result.Key;
var cityName = result.EnglishName;
return {cityCode, cityName};
});
}).on("error", (err) => {
return err;
console.log("Error: " + err.message);
});
return result;
}
getCityCode(latLongCityCodeURL)
.then((res) => {
console.log(res.cityCode, res.cityName)
})
Your code block runs in a synchronized way and console.log part hits just after http.get call. The thing is http.get is an async function and its callback part will be called future ticks of NodeJS when your response has arrived.
var http = require('http');
var latLon = "40.8,-77.8"; //Lat/lon
var cityCode = ""; //City code
var cityName = "";
var latLongCityCodeURL = ("http://dataservice.accuweather.com/locations/v1/cities/geoposition/search?apikey=" + "fmKWSgaG5EAA0diCP2lSREEOYG6PC5q9" + "&q=" + latLon);
var that;
//Current Conditions Vars
var ccWeatherText = ""; //Text for weather at location
var ccTemp = 0; //Degrees Farenheit
var ccIcon = 0; //weather icon number https://developer.accuweather.com/weather-icons
var ccURL = "test"; //URL for get
//12 hour forecast Conditions Vars
//5 day forecast conditions Vars
//Get city code
getWeather = url => {
return new Promise((resolve, reject) => {
http.get(url, res => {
let body = '';
res.on('data', chunk => resolve(JSON.parse(chunk)));
}).on('error', reject);
});
};
getWeather(latLongCityCodeURL).then( weather => {
console.log(weather.Key + " " + weather.EnglishName);
})
You must wait for the response, then send the other requests or log into. The scope isn't really the issue here, it's the order of operations that you're missing. You define a variable, then wait for a HTTP request, meanwhile you're immediately logging a value, then the request finishes (or times out or other error), and you can log again the value - at which point you see data.
In other words, to fix the issue, other requests must be made from within a function of resp.on("end", which says when you've finished getting all data chunks
And by "within", the code can still be in a separate method, outside those brackets, but you must call that particular function from within that response body.
You should pass such asynchronous returned data through parameter variables, not update some external, global state in most cases
So I'm working on this Zipline for my free code camp and am pretty much done, i'm just trying to implement a search. I have it working ok but have a couple of bugs.
What i'm doing for the search is that i'm creating a new array then i'm filtering it and comparing it to the text input of the user and if its equal then i will push that value onto a new array then display it on the screen.
is there a better way to do this? so that as the user types it is comparing with the list of arrays I have.
Thanks
Here is the jsfiddle http://jsfiddle.net/wtj7s6c6/2/
$(document).ready(function () {
var img, user, status, channel,
url = "https://api.twitch.tv/kraken/",
/* cb = '?client_id=5j0r5b7qb7kro03fvka3o8kbq262wwm&callback=?',*/
cb = '?callback=?',
//create new array from filtered array
newArray = [],
userList = ["freecodecamp", "maximilian_dood", "UltraChenTV", "habathcx", "TeamSpooky", "Nuckledu", "medrybw"];
/*function updateLog(message) {
$("#log").html($("#log").html() + "<p>" + message + "</p>");
};*/
function addOnlineUser(image, username, status) {
$(".people")
.append('<li><img class="picture" src="' + image + '"/><span class="username">' + username + '</span><span class="isOnline">✔</span><p class="status">' + status + '</p></li>');
};
function addOfflineUser(image, username) {
if (image != null) $(".people")
.append('<li><img class="picture" src="' + image + '"/> <span class="username">' + username + '</span><span class="isOffline">!</span></li>');
else $(".people")
.append('<li><img class="picture emptypic"/><span class="username">' + username + '</span><span class="isOffline">!</span></li>');
};
function clickOnline() {
userList.forEach(function (name) {
$.getJSON(url + 'streams/' + name + cb)
.success(function (data) {
if (data.stream !== null) {
img = data.stream.channel.logo;
user = data.stream.channel.display_name;
status = data.stream.channel.status;
channel = data._links.channel;
addOnlineUser(img, user, status);
}
});
});
};
function clickOffline() {
userList.forEach(function (name) {
$.getJSON(url + 'streams/' + name + cb)
.success(function (data) {
if (data.stream === null) {
$.getJSON(url + 'users/' + name + cb)
.success(function (data2) {
img = data2.logo;
user = data2.display_name;
channel = data2._links.self;
addOfflineUser(img, user);
});
}
});
});
};
function clickSearchOff(array) {
array.forEach(function (name) {
$.getJSON(url + 'streams/' + name + cb)
.success(function (data) {
if (data.stream === null) {
$.getJSON(url + 'users/' + name + cb)
.success(function (data3) {
img = data3.logo;
user = data3.display_name;
channel = data3._links.self;
addOfflineUser(img, user);
});
}
});
});
};
function clickSearchOn(array) {
array.forEach(function (name) {
$.getJSON(url + 'streams/' + name + cb)
.success(function (data4) {
if (data4.stream !== null) {
img = data4.stream.channel.logo;
user = data4.stream.channel.display_name;
status = data4.stream.channel.status;
channel = data4._links.channel;
addOnlineUser(img, user, status);
}
});
});
};
$(".online").on('click', function () {
$(".people").empty();
clickOnline();
});
$(".offline").on('click', function () {
$(".people").empty();
clickOffline();
});
$(".all").on('click', function () {
$(".people").empty();
clickOnline();
clickOffline();
});
$(".all").click();
$('input[type="text"]').keyup(function () {
var searchTerm = $(this).val();
searchTerm = searchTerm.toLowerCase();
console.log("Search term:" + searchTerm);
//empty screen//
$(".people").empty();
var newArray = [];
for (var i = 0; i < userList.length; i++) {
if (userList[i].indexOf(searchTerm) != -1) {
newArray.push(userList[i]);
}
}
console.log("New array: " + newArray);
clickSearchOff(newArray);
clickSearchOn(newArray);
});
})
I suggest (as I may do) implement some kind of buffer on the keyup event in order to not always trigger the comparison, only after one or two seconds pass after the last keyup trigger:
var compareTimeout;
$('input[type="text"]').keyup(function () {
clearTimeout(compareTimeout);
compareTimeout = setTimeout(function () {
var searchTerm = $(this).val();
searchTerm = searchTerm.toLowerCase();
console.log("Search term:" + searchTerm);
//empty screen//
$(".people").empty();
var newArray = [];
for (var i = 0; i < userList.length; i++) {
if (userList[i].indexOf(searchTerm) != -1) {
newArray.push(userList[i]);
}
}
console.log("New array: " + newArray);
clickSearchOff(newArray);
clickSearchOn(newArray);
}, 2000);
});
This would make the function run only after 2 seconds after the last keyup event, and not every time the user types a letter in the input.
I would like to make a program that can keep track of multiple stock objects and display basic information about them (IE: their price).
I have this code which can successfully retrieve the price of the stock:
function getStock(symbol, callback){
var url = 'https://query.yahooapis.com/v1/public/yql';
var data = encodeURIComponent("select * from yahoo.finance.quotes where symbol in ('" + symbol + "')");
$.getJSON(url, 'q=' + data + "&format=json&diagnostics=true&env=http://datatables.org/alltables.env")
.done(function (data) {
result = data.query.results.quote.LastTradePriceOnly;
callback(result);
})
.fail(function (jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log('Request failed: ' + err);
});
}
getStock("goog", function(){alert(result)});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I would like to be able to create a simple object that can keep track of a stock. However, I have problems with asynchrony and the JSON request. Here is my code with the "stock" object:
function getStock(symbol, callback) {
var url = 'https://query.yahooapis.com/v1/public/yql';
var data = encodeURIComponent("select * from yahoo.finance.quotes where symbol in ('" + symbol + "')");
$.getJSON(url, 'q=' + data + "&format=json&diagnostics=true&env=http://datatables.org/alltables.env")
.done(function(data) {
result = data.query.results.quote.LastTradePriceOnly;
callback(result);
})
.fail(function(jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log('Request failed: ' + err);
});
}
function stock(symbol) {
this.price = 0;
getStock(symbol, function(result) { //this function is my callback
console.log(result);
this.price = result;
});
this.printPrice = function() {
alert("The price is: " + this.price);
}
}
var s = new stock("goog");
$("#button").click(function() {
s.printPrice()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Print Price</button>
As you may notice, I tried using a callback which seems to be the appropriate solution to this problem (new to Javascript). However, it doesn't seem to actually be setting the class variable. In the console it does print the correct price, but it doesnt seem to change "this.price" (which is what I need it to do)
Any advice as to why this doesn't work, or how to create an "updateStockPrice()" method would be really helpful.
I put together a jQuery plugin for this. Hope this can be helpful for someone
<!-- import jQuery and the plugin -->
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/jquery-stockquotes/dist/jquery.stockquotes.js"></script>
<link rel="stylesheet" type="text/css" href="bower_components/jquery-stockquotes/dist/jquery.stockquotes.css" />
<!-- the HTML integration -->
Twitter: <span class="stock-quote" data-symbol="TWTR"></span>
Facebook: <span class="stock-quote" data-symbol="FB"></span>
Google: <span class="stock-quote" data-symbol="GOOGL"></span>
Netflix: <span class="stock-quote" data-symbol="NTFLX"></span>
Yahoo: <span class="stock-quote" data-symbol="YHOO"></span>
<!-- the JS integration -->
<script>
$(document).on('ready', function () {
$('.stock-quote').stockQuotes();
});
</script>
https://github.com/ajwhite/jquery-stockquotes
The this you are calling on
s.printPrice()
is no longer in the same scope to be able to use
alert("The price is: " + this.price);
So add a reference to the initial this to further access its variable in your class:
var that = this;
function getStock(symbol, callback) {
var url = 'https://query.yahooapis.com/v1/public/yql';
var data = encodeURIComponent("select * from yahoo.finance.quotes where symbol in ('" + symbol + "')");
$.getJSON(url, 'q=' + data + "&format=json&diagnostics=true&env=http://datatables.org/alltables.env")
.done(function(data) {
result = data.query.results.quote.LastTradePriceOnly;
callback(result);
})
.fail(function(jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log('Request failed: ' + err);
});
}
function stock(symbol) {
var that = this;
that.price = 0;
getStock(symbol, function(result) { //this function is my callback
console.log(result);
console.log("1");
that.price = result;
});
that.printPrice = function() {
alert("The price is: " + that.price);
}
}
var s = new stock("goog");
$("#button").click(function() {
s.printPrice()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Print Price</button>
I Just changed the var price to the top, to make it declared global for the functions. This way, they all share it and you´ll be able to print it.
Hope it´ll help you!!
function getStock(symbol, callback) {
var url = 'https://query.yahooapis.com/v1/public/yql';
var price=0;
var data = encodeURIComponent("select * from yahoo.finance.quotes where symbol in ('" + symbol + "')");
$.getJSON(url, 'q=' + data + "&format=json&diagnostics=true&env=http://datatables.org/alltables.env")
.done(function(data) {
result = data.query.results.quote.LastTradePriceOnly;
callback(result);
})
.fail(function(jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log('Request failed: ' + err);
});
}
function stock(symbol) {
getStock(symbol, function(result) { //this function is my callback
console.log(result);
price = result;
});
this.printPrice = function() {
alert("The price is: " + price);
}
}
var s = new stock("goog");
$("#button").click(function() {
s.printPrice()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Print Price</button>
function getStock(symbol, callback) {
var url = 'https://query.yahooapis.com/v1/public/yql';
var data = encodeURIComponent("select * from yahoo.finance.quotes where symbol in ('" + symbol + "')");
$.getJSON(url, 'q=' + data + "&format=json&diagnostics=true&env=http://datatables.org/alltables.env")
.done(function(data) {
result = data.query.results.quote.LastTradePriceOnly;
callback(result);
})
.fail(function(jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log('Request failed: ' + err);
});
}
function stock(symbol) {
this.price = 0;
getStock(symbol, function(result) { //this function is my callback
console.log(result);
this.price = result;
});
this.printPrice = function() {
alert("The price is: " + this.price);
}
}
var s = new stock("goog");
$("#button").click(function() {
s.printPrice()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Print Price</button>
It is time to say hello to ES5 and bind method to set execution context.
Stock.getStock now returns promise - after click ther will be executed query for the latest price of the stock.
function getStock(symbol, callback) {
var url = 'https://query.yahooapis.com/v1/public/yql';
var data = encodeURIComponent("select * from yahoo.finance.quotes where symbol in ('" + symbol + "')");
$.getJSON(url, 'q=' + data + "&format=json&diagnostics=true&env=http://datatables.org/alltables.env")
.done(function (data) {
result = data.query.results.quote.LastTradePriceOnly;
callback(result);
})
.fail(function (jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log('Request failed: ' + err);
});
}
function Stock(symbol) {
this.price = 0;
this.getStock = function () {
var dfd = jQuery.Deferred();
getStock(symbol, function (result) {
this.price = result;
dfd.resolve(result);
}.bind(this));
return dfd.promise();
}.bind(this);
this.printPrice = function () {
alert("The price is: " + this.price);
}.bind(this);
}
var s = new Stock("goog");
$("#button").click(function () {
s.getStock().then(s.printPrice).done();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Print Price</button>