javascript comparing input to an array live search - javascript

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.

Related

I want to make a private chat for every user since all the user's chat are showing in a same view

I'm trying to make a chat application using spring boot and I am stuck. This is my Frontend (custom.js) code. I want to make a separate chat view for every specific user since all user's chat which is entered in this are showing on the same view. I have given an image link in this for a better explanation if anyone could help...
custom.js
let $chatHistory;
let $button;
let $textarea;
let $chatHistoryList;
function init() {
cacheDOM();
bindEvents();
}
function bindEvents() {
$button.on('click', addMessage.bind(this));
$textarea.on('keyup', addMessageEnter.bind(this));
}
function cacheDOM() {
$chatHistory = $('.chat-history');
$button = $('#sendBtn');
$textarea = $('#message-to-send');
$chatHistoryList = $chatHistory.find('ul');
}
function render(message, userName) {
scrollToBottom();
// responses
var templateResponse = Handlebars.compile($("#message-response-template").html());
var contextResponse = {
response: message,
time: getCurrentTime(),
userName: userName
};
setTimeout(function () {
$chatHistoryList.append(templateResponse(contextResponse));
scrollToBottom();
}.bind(this), 1500);
}
function sendMessage(message) {
let username = $('#userName').val();
console.log(username)
sendMsg(username, message);
scrollToBottom();
if (message.trim() !== '') {
var template = Handlebars.compile($("#message-template").html());
var context = {
messageOutput: message,
time: getCurrentTime(),
toUserName: selectedUser
};
$chatHistoryList.append(template(context));
scrollToBottom();
$textarea.val('');
}
}
function scrollToBottom() {
$chatHistory.scrollTop($chatHistory[0].scrollHeight);
}
function getCurrentTime() {
return new Date().toLocaleTimeString().replace(/([\d]+:[\d]{2})(:[\d]{2})(.*)/, "$1$3");
}
function addMessage() {
sendMessage($textarea.val());
}
function addMessageEnter(event) {
// enter was pressed
if (event.keyCode === 13) {
addMessage();
}
}
init();
chat.js
const url = 'http://localhost:8080';
let stompClient;
let selectedUser;
let newMessages = new Map();
function connectToChat(userName) {
console.log("connecting to chat...")
let socket = new SockJS(url + '/chat');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log("connected to: " + frame);
stompClient.subscribe("/topic/messages/" + userName, function (response) {
let data = JSON.parse(response.body);
if (selectedUser === data.fromLogin) {
render(data.message, data.fromLogin);
} else {
newMessages.set(data.fromLogin, data.message);
$('#userNameAppender_' + data.fromLogin).append('<span id="newMessage_' + data.fromLogin + '" style="color: red">+1</span>');
}
});
});
}
function sendMsg(from, text) {
stompClient.send("/app/chat/" + selectedUser, {}, JSON.stringify({
fromLogin: from,
message: text
}));
}
function registration() {
let userName = document.getElementById("userName").value;
$.get(url + "/registration/" + userName, function (response) {
connectToChat(userName);
}).fail(function (error) {
if (error.status === 400) {
alert("Login is already busy!")
}
})
}
function selectUser(userName) {
console.log("selecting users: " + userName);
selectedUser = userName;
let isNew = document.getElementById("newMessage_" + userName) !== null;
if (isNew) {
let element = document.getElementById("newMessage_" + userName);
element.parentNode.removeChild(element);
render(newMessages.get(userName), userName);
}
$('#selectedUserId').html('');
$('#selectedUserId').append('Chat with ' + userName);
}
function fetchAll() {
$.get(url + "/fetchAllUsers", function (response) {
let users = response;
let usersTemplateHTML = "";
for (let i = 0; i < users.length; i++) {
usersTemplateHTML = usersTemplateHTML + '<a href="#" onclick="selectUser(\'' + users[i] + '\')"><li class="clearfix">\n' +
' <img src="https://rtfm.co.ua/wp-content/plugins/all-in-one-seo-pack/images/default-user-image.png" width="55px" height="55px" alt="avatar" />\n' +
' <div class="about">\n' +
' <div id="userNameAppender_' + users[i] + '" class="name">' + users[i] + '</div>\n' +
' <div class="status">\n' +
' <i class="fa fa-circle offline"></i>\n' +
' </div>\n' +
' </div>\n' +
' </li></a>';
}
$('#usersList').html(usersTemplateHTML);
});
}

RGraph hide line plus labels with a click on key element

So, I have a graph like this:
What I'm trying to achieve is to hide the lines plus the labels with it when I click the key referring that line.
I found this on the docs and I tried doing this:
$(line.canvas).on('click', function (e) //line is the name of the graph of both green and red lines
{
var key = RGraph.Registry.get('key-element');
console.log(key);
if (key) {
console.log("true");
}
});
I found this to be pointless due the fact when I click on the keys they return weird outputs, either null or other key different from the one I want.
What I also found on RGraph Line API is that obj.hide([index]) only sets the color to rgba(0,0,0,0), which does not hide the labelsAbove property.
How can I fix this and make a proper hide of the lines when I click on the key?
Well this demo hides/shows the line but the labelsAbove labels are still there. So I'll have to look at this for the next beta.
Here's the code:
function createandcall(rackname, racknameid, stb) {
$('#maintable').append('<table class="table"><tbody><tr style="text-align:center"><td><h2>' + rackname + '</h2><table class="table"><tbody style="text-align:left"><tr id="STBL"></tr><tr id="STBL1"></tr><tr id="STBL2"></tr><tr id="STBL3"></tr></tbody></table></td></tr></tbody></table>');
for (i = 1; i < stb + 1; i++) {
createtable(i);
callstb(rackname, racknameid, i);
}
return;
}
function callstb(rackname, racknameid, i) {
$.ajax({
type: "GET",
dataType: 'text',
url: "http://localhost:3000/index/" + rackname + ' ' + racknameid + ' ' + i,
success: function (data) {
response = '\#stb' + i;
idtd = '\#tdstb' + i;
$(response).html(data.replace(/\[32m/gi, '').replace(/\[0\;33m/gi, '').replace(/\[0m/gi, '').replace(/\[33m/gi, '').replace(/\[37m/gi, '').replace(/\[31m/gi, ''));
pre = $(response).html().toString();
},
error: function (error) {
$("#error").html('Error trying to get the STBs report');
$("#error").show();
}
})
}
server.js:
app.get('/index/*', (req, res) => {
parsedparam = req.params[0].split(" ")
rackname = parsedparam[0]
racknameid = parsedparam[1]
stb = parseInt(parsedparam[2])
verifystbs(rackname, racknameid, stb, res);
});
function openconnection() {
con.connect(() => { console.log("RackChecker connected with database!") });
}
function closeconnection() {
con.end(() => { console.log("Connection Closed") });
}
function verifystbs(rackname, racknameid, stb, res) {
openconnection();
con.query("SELECT (SELECT UCASE(name) FROM models WHERE s.model = id) as Model,\
(SELECT UCASE(name) FROM manufacturers WHERE s.manufacturer = id) as Branch,\
(SELECT UCASE(name) FROM racks WHERE s.rack = id) as Rack,\
s.name as Stb,\
x.pr as Jira, \
x.reason as Reason,\
x.requestor AS Stress_Request,\
x.version as Version\
FROM \
stbs s \
LEFT JOIN \
stressrun x \
ON (s.active = 1 && s.rack = (SELECT id FROM racks WHERE name = '"+ racknameid + "')) \
WHERE x.id = (SELECT max(id) FROM stressrun y WHERE y.stb_id = s.id) and s.name like ('STB_%"+ stb + "')\
and x.reason in ('failed','other','new build') ORDER BY s.name;", (err, result) => {
console.log(result)
if (!Array.isArray(result) || !result.length) {
callnewstb = shell.exec('./shellscript/callnewstb.sh ' + rackname + ' ' + stb, { async: true });
callnewstb.stdout.on('data', (data) => {
res.send(data);
});
}
else {
for (i = 0; i < result.length; i++) {
parsestbnumber = result[i].Stb.split("_");
stbnumber = parseInt(parsestbnumber[1]);
stbnumber = stbnumber * 1;
if (stb == stbnumber) {
res.send("Stress Test is not running on <b>" + result[i].Stb + "</b><br>Reason: <b>" + result[i].Reason + "</b><br>Jira Ticket: <b><a href='https://link.jira.com/browse/" + result[i].Jira + "'>" + result[i].Jira + "</a></b><br>Build Version: <b>" + result[i].Version)
break
}
else {
callnewstb = shell.exec('./shellscript/callnewstb.sh ' + rackname + ' ' + stb, { async: true });
callnewstb.stdout.on('data', (data) => {
res.send(data);
})
}
}
}
});
closeconnection();
}

How to make option filed in PHP(HTML) with jQuery script

How to make HTML option filed in PHP file with jQuery?
I want to integrate simplybook.me api in my website.
The URL of the API is: https://simplybook.me/api/explorer there is Filter performers by service.
I want to make option fields of my services ad services provider list in PHP site.
<script>
var loginClient = new JSONRpcClient({
'url': '//user-api.simplybook.me/login',
'onerror': function (error) {
alert(error);
}
});
var token = loginClient.getToken('narendra', '5501cb0d7052b9d95ba78559ed41cd65c7bc0d3a51e21e259cbe092142f7537e');
var loginClient = new JSONRpcClient({
'url': '//user-api.simplybook.me/login',
'onerror': function (error) {
alert(error);
}
});
var token = loginClient.getToken('narendra', '5501cb0d7052b9d95ba78559ed41cd65c7bc0d3a51e21e259cbe092142f7537e');
var client = new JSONRpcClient({
'url': 'https://user-api.simplybook.me/',
'headers': {
'X-Company-Login': 'narendra',
'X-Token': token
},
'onerror': function (error) {
alert(error);
}
});
var services = client.getEventList();
var performers = client.getUnitList();
var serviceId;
var performerId;
jQuery('#select_event_id').empty();
jQuery('#select_unit_id').empty();
jQuery('#select_event_id').append('<option value=""></option>');
jQuery('#select_unit_id').append('<option value=""></option>');
for (var id in services) {
jQuery('#select_event_id').append('<option value="' + id + '">' +
services[id].name + '</option>');
}
for (var id in performers) {
jQuery('#select_unit_id').append('<option value="' + id + '">' +
performers[id].name + '</option>');
}
jQuery('#select_event_id').change(function () {
// service id
serviceId = jQuery(this).val();
var selectedService = services[serviceId];
// filter available performers
if (selectedService) {
if (typeof(selectedService.unit_map) != 'undefined' &&
selectedService.unit_map.length) {
jQuery('#select_unit_id option').attr('disabled', true);
jQuery('#select_unit_id option[value=""]').attr('disabled', false);
for (var i = 0; i < selectedService.unit_map.length; i++) {
jQuery('#select_unit_id option[value="' +
selectedService.unit_map[i] + '"]').attr('disabled', false);
}
} else {
jQuery('#select_unit_id option').attr('disabled', false);
}
}
jQuery('#eventId').val(serviceId).change();
});
jQuery('#select_unit_id').change(function () {
performerId = jQuery(this).val();
});
And there is my website URL where I can use this code:
http://dev.dissertationconsulting.co.uk/bookingsystem/cllogin.php

Repeated video duration values in asnyc to videoId - Youtube API v3

I'm having a problem with the asynchronous methods that prints and returns all vidDuration values then viewCount values were placed for each videoId, but vidDuration repeated only the last value that was received and assigned it to all of the videoIds which is clearly wrong.
I tried setting up a temporary array called tempArray within the loop that store each of the vidDuration values which it did, then to print them to each vidDuration, but then again, it looped through the output however many values are in the array and duplicated the videos, which I don't want. I commented out lines involving tempArray and reverted back to the working problem.
From what I understand, the async methods printed all of the duration values without going to the output as if it got stuck there until it was done and resolved and then it looped the viewCount and output perfectly fine. I'm wondering how do I fix this in a programmatically logical way?
Script:
var channelName = 'ExampleChannel';
var vidWidth = 500;
var vidHeight = 400;
var vidResults = 15; /* # of videos to show at once - max 50 */
var vidDuration = "";
var viewCount = 0;
var videoId = "";
$(document).ready(function() {
$.get( // get channel name and load data
"https://www.googleapis.com/youtube/v3/channels",
{
part: 'contentDetails',
forUsername: channelName,
key: 'XXXXXXXX'
},
function(data)
{
$.each(data.items,
function(i, item) {
console.log(item); // log all items to console
var playlistId = item.contentDetails.relatedPlaylists.uploads;
getPlaylists(playlistId);
})
}
);
// function that gets the playlists
function getPlaylists(playlistId)
{
$.get(
"https://www.googleapis.com/youtube/v3/playlistItems",
{
part: 'snippet',
maxResults: vidResults,
playlistId: playlistId,
key: 'XXXXXXXX'
},
// print the results
function(data)
{
var output;
/*var tempArray = new Array();*/ // temporary array for storing video duration values
$.each(data.items,
function(i, item) {
console.log(item);
var vidTitle = item.snippet.title; // video title
var vidDesc = item.snippet.description; // video description
var videoId = item.snippet.resourceId.videoId; // video id
// check if description is empty
if(vidDesc == null || vidDesc == "")
{
vidDesc = "No description was written."; // FIX: test msg to see where it still shows up
$('#desc').remove(); // remove video description
}
else vidDesc = item.snippet.description;
getVideoDuration(videoId).done(function(r){
vidDuration = r;
console.log(r);
/*tempArray[i] = r;*/ // store value into each array index
/*console.log("Array:", tempArray[i], tempArray);*/ // log to console
/*i++;*/ // increment
getViewCount(videoId).done(function(r){
viewCount = r;
console.log(r);
//vidDuration = getVideoDuration(videoId);
//viewCount = getViewCount(videoId);
// temp array index to loop thru array
/*$.each(tempArray, function(i){
vidDuration = tempArray[i]; // assign index value to vidDuration
console.log("In Each vidDuration: ", vidDuration);
i++;
});*/
console.log("id: " + videoId + " duration: " + vidDuration + " viewCount: " + viewCount); // return value in console
output = '<li><iframe height="' + vidHeight + '" width="' + vidWidth + '" src=\"//www.youtube.com/embed/' + videoId + '\"></iframe></li><div id="title">' + vidTitle + '</div><div id="desc">' + vidDesc + '</div><div id="duration">Length: ' + vidDuration + '</div><div id="stats">View Count: ' + viewCount + '</div>';
// Append results to list tag
$('#results').append(output);
}); // end of getVideoDuration(videoId).done
}); // end of getViewCount(videoId).done
});
/*console.log("TEMPARRAY[]",tempArray);*/ // print entire array
}
);
}
// return video duration
function getVideoDuration(videoId)
{
var defer1 = $.Deferred();
var r = '';
$.get(
"https://www.googleapis.com/youtube/v3/videos",
{
part: 'contentDetails',
id: videoId,
key: 'XXXXXXXX',
},
function(data)
{
$.each(data.items,
function(i, item) {
r = item.contentDetails.duration;
defer1.resolve(r);
console.log("in vidDuration func", r);
});
}
);
return defer1.promise();
}
// return video view count
function getViewCount(videoId)
{
var defer2 = $.Deferred();
var r = '';
$.get(
"https://www.googleapis.com/youtube/v3/videos",
{
part: 'contentDetails, statistics',
id: videoId,
key: 'XXXXXXXX',
},
function(data)
{
$.each(data.items,
function(i, item) {
r = item.statistics.viewCount;
defer2.resolve(r);
console.log("in viewCount func", r);
});
}
);
return defer2.promise();
}
});
Screenshot results (normal refresh):
Screenshot results (using debugger):
Here's a screenshot of the results when stepping through with the debugger console. (Why are the results different from when the page normally loads? Is this typical action of the async methods? How do I fix this?)
In fact the second promise is misplaced, the second promise is resolved AFTER that all the promises from the first promise have been resolved, so the last value is save. logical
Now if you resolve the first promise WHEN second is resolved one by one you are able to correct the problem.
var view = 0;
r = item.contentDetails.duration; // video duration
getViewCount(videoId).done(function(t){
view = t;
dfrd1.resolve(r, view);
});
Check the screenshot:
I change a bit the code to solve the problem.
var channelName = 'example';
var vidWidth = 500;
var vidHeight = 400;
var vidResults = 15; /* # of videos to show at once - max 50 */
var vidDuration = "";
var viewCount = 0;
var videoId = "";
$(document).ready(function() {
$.get( // get channel name and load data
"https://www.googleapis.com/youtube/v3/channels",
{
part: 'contentDetails',
forUsername: channelName,
key: 'xxx'
},
function(data)
{
$.each(data.items,
function(i, item) {
//console.log(item); // log all items to console
var playlistId = item.contentDetails.relatedPlaylists.uploads;
//var viewCount = console.log(item.statistics.viewCount);
getPlaylists(playlistId);
});
}
);
// function that gets the playlists
function getPlaylists(playlistId)
{
$.get(
"https://www.googleapis.com/youtube/v3/playlistItems",
{
part: 'snippet',
maxResults: vidResults,
playlistId: playlistId,
key: 'xxx'
},
// print the results
function(data)
{
var output;
$.each(data.items,
function(i, item) {
console.log(item);
var vidTitle = item.snippet.title; // video title
var vidDesc = item.snippet.description; // video description
var videoId = item.snippet.resourceId.videoId; // video id
// check if description is empty
if(vidDesc == null || vidDesc == "")
{
vidDesc = "No description was written."; // FIX: test msg to see where it still shows up
$('#desc').remove(); // remove video description
}
else vidDesc = item.snippet.description;
getVideoDuration(videoId).done(function(d, v){
vidDuration = d;
//console.log(r);
viewCount = v;
document.write("id: " + videoId + " duration: " + vidDuration + " viewCount: " + viewCount); // return value in console
document.write("<br>");
output = '<li><iframe height="' + vidHeight + '" width="' + vidWidth + '" src=\"//www.youtube.com/embed/' + videoId + '\"></iframe></li><div id="title">' + vidTitle + '</div><div id="desc">' + vidDesc + '</div><div id="duration">Length: ' + vidDuration + '</div><div id="stats">View Count: ' + viewCount + '</div>';
// Append results to list tag
$('#results').append(output);
});
});
}
);
}
// return video duration
function getVideoDuration(videoId)
{
var dfrd1 = $.Deferred();
var r = '';
$.get(
"https://www.googleapis.com/youtube/v3/videos",
{
part: 'contentDetails',
id: videoId,
key: 'xxx',
},
function(data)
{
$.each(data.items,
function(i, item) {
//videoId = item.snippet.resourceId.videoId;
var view = 0;
r = item.contentDetails.duration; // video duration
getViewCount(videoId).done(function(t){
view = t;
dfrd1.resolve(r, view);
});
//alert(videoId);
});
}
);
return dfrd1.promise();
}
// return video view count
function getViewCount(videoId)
{
var dfrd2 = $.Deferred();
var r = '';
$.get(
"https://www.googleapis.com/youtube/v3/videos",
{
part: 'contentDetails, statistics',
id: videoId,
key: 'xxx',
},
function(data)
{
$.each(data.items,
function(i, item) {
//videoId = item.snippet.resourceId.videoId;
r = item.statistics.viewCount; // view count
//alert(videoId);
dfrd2.resolve(r);
// console.log("in", r);
});
}
);
return dfrd2.promise();
}
});

How to create a Javascript object that keeps track of a stock price?

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>

Categories

Resources