CSS selector is not working using jQuery - javascript

instructions for the project is to
create a simple web page application that allows the user to enter one or more stock ticker symbols and
display price information about these stocks.
• Data has to come from a REST API (https://www.alphavantage.co), it is free to use and returns JSON
formatted output.
Here is my code so far and I'm not being able to figure it out
UPDATED
when a user types a symbol, it's not showing anything on the console. how can I make it that for every symbol a user inputs , it fetches the price from the url and gives price.
$(document).ready(function() {
$('#searchstock').on('click', function() {
let requestData = $('search').val();
let resultElement = $('stock');
// Make request to rest API
$.ajax({
url: 'https://www.alphavantage.co/query?function=BATCH_STOCK_QUOTES&symbols=' + requestData + '&apikey=SB1CZMKQ6Q5283QZ',
method: 'get',
data: {
symbols: requestData
},
dataType: 'json',
success: function(data) {
console.log(data);
resultElement.html('price:' + data.Stock_Quotes[0])
}
});
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Stocks</title>
<!-- Bootstrap core CSS -->
<link href="https://bootswatch.com/4/simplex/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="searchContainer">
<h1>Enter symbol</h1>
<p class="lead">Enter a a symbol to fetch a price </p>
<input type="text" id="search" class="form-control" placeholder="Stock symbol...">
</div>
<br>
<button type="button" id="searchstock" class="btn btn-info">Get price</button>
<br>
<div id="stock"></div>
</div>
<!-- /.container -->
<script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- script src="js/main.js"></script -->
</body>
</html>

You expected this line to match the input having its id attribute set to "search":
let requestData = $('search').val();
jQuery select function requires a CSS selector as its first argument. Now in your code, the CSS selector you give to $ function is'search' and this actually means «Please match elements having their name being "search"» and not «Match elements having their id attribute set to "search"».
Do you see the difference ?
Simply change $('search').val(); to $('#search').val(); as # tells to match the "id" attribute.
The same goes for this line.
let resultElement = $('stock');
You also have a property name issue.
Querying for "MSFT" will return something like:
{
// …
"Stock Quotes": [
{
"1. symbol": "MSFT",
"2. price": "93.0300",
"3. volume": "--",
"4. timestamp": "2018-03-02 15:59:59"
}
]
}
As you can see, the data object property is called "Stock Quotes" and not Stock_Quotes as you put it in your code.
As the property name contains space, square brackets notation is required to access this entry. Retrieving the price for the first result will look like this:
resultElement.html('price:' + data["Stock Quotes"][0]["2. price"])

Try making use of oninput instead of onclick if you want to execute search/ajax-call whenever a user types a symbol.
$('#search').on('input', function(e) {
var resultElement = $('#stock'),
requestData = $(this).val();
// Make request to rest API
$.ajax({
url: 'https://www.alphavantage.co/query?function=BATCH_STOCK_QUOTES&symbols=' + requestData + '&apikey=SB1CZMKQ6Q5283QZ',
method: 'get',
data: {
symbols: requestData
},
dataType: 'json',
success: function(data) {
console.log(data);
resultElement.html('price:' + data["Stock Quotes"][0]["2. price"])
}
});
});

Related

How can I access a specific element within the Our World in Data COVID-19 Master Vaccinations JSON File?

I'm relatively new to coding and am trying to access a specific element within COVID Vaccine JSON file created by Our World in Data, but I'm having a hard time with the syntax of my code/the structure of the JSON file.
I've successfully consumed the data from the JSON file (it's appearing in my inspector of the HTML page), but now I want to be able to call out a specific data field to display it in my HTML.
For example, I wanted the total number of people vaccinated in the United States on 04-07-2021 and was trying to the code below, but received Cannot read property 'United States of undefined as an error. Also, for context on my approach, I haven't learned how to use one of the frameworks yet, so I'm doing some DOM manipulation to get the data to display in the HTML.
//110 is the total number of days that US vaccination data has been tracked, according to my math
var settings = {
"url": "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/vaccinations/vaccinations.json",
"method": "GET",
"timeout": 0,
$.ajax(settings).done(function (response) {
JSON.parse(response);
console.log(response);
var content = response["country"]["United States"]["date"][110];
document.getElementById("admin").innerHTML = response;
});
I also tried the following, which is also throwing errors:
var settings = {
"url": "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/vaccinations/vaccinations.json",
"method": "GET",
"timeout": 0,
};
$.ajax(settings).done(function (response) {
JSON.parse(response);
console.log(response);
var content = response.country[264].data.date[110]"
document.getElementById("admin").innerHTML = response;
});
This is my first time writing code for a GET API call, so any and all feedback are welcome! For reference, the raw JSON file can be found here and their GitHub can be found here (file is named vaccinations.json). My HTML is also included below for additional context. Thanks in advance!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vaccine Visualization</title>
<!--enabled with jQuery-->
<<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script src="vaccines.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Archivo:wght#400;600;800&family=Staatliches&display=swap"
rel="stylesheet">
<link href="vaccines-stylesheet.css" rel="stylesheet">
<style></style>
</head>
<body>
<div class="triangle">
<div class="content">
<h1 class="header"> International COVID Vaccine Rollout </h1>
<h2 class="subheader">PERCENT COMPLETE BY COUNTRY</h2>
</div>
</div>
<div class="triangle2"></div>
<div class="top-five-widget">
<h2 class="top-five-title"> COVID Vaccine Distribution:<br>Top Five Countries</h2>
<p>Total Vaccines Administered:</p>
<span id="admin"></span>
</div>
<script src="vaccines.js"></script>
</body>
</html>
This should display the number of people vaccinated on '2021-04-07'
var settings = {
"url": "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/vaccinations/vaccinations.json",
"method": "GET",
"timeout": 0,
};
$.ajax(settings).done(function (response) {
const USA = JSON.parse(response).find((data) => data.country === 'United States');
const peopleVaccinated = USA.data.find((d) => d.date === '2021-04-07').people_vaccinated;
document.getElementById("admin").innerHTML = peopleVaccinated;
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vaccine Visualization</title>
<!--enabled with jQuery-->
<<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script src="vaccines.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Archivo:wght#400;600;800&family=Staatliches&display=swap"
rel="stylesheet">
<link href="vaccines-stylesheet.css" rel="stylesheet">
<style></style>
</head>
<body>
<div class="triangle">
<div class="content">
<h1 class="header"> International COVID Vaccine Rollout </h1>
<h2 class="subheader">PERCENT COMPLETE BY COUNTRY</h2>
</div>
</div>
<div class="triangle2"></div>
<div class="top-five-widget">
<h2 class="top-five-title"> COVID Vaccine Distribution:<br>Top Five Countries</h2>
<p>Total Vaccines Administered:</p>
<span id="admin"></span>
</div>
<script src="vaccines.js"></script>
</body>
Explanation
The response is an array of objects, each object has a key of country.
So when I do a .find, it loops through the array looking for an object with a key of country equal to "United States" and saves it in a variable USA.
Which is what this line is doing.
const USA = JSON.parse(response)
.find((data) => data.country === 'United States');
USA itself is another object that has a key of data which is an array of objects.
So I do another .find on USA.data for the object with a key of date that is equal to '2021-04-07', and when it finds it we immediately chain .people_vaccinated to it.
That is this line:
const peopleVaccinated = USA.data
.find((d) => d.date === '2021-04-07').people_vaccinated;
The rest should make sense to you.
Consider checking out How can I access and process nested objects, arrays, or JSON? Like someone suggested in the comments.

openweathermap weather data by zip code not working?

i need to make it so that when a zip code is typed into the box and the submit button is clicked, the name of the city shows up under it. when i click the button after putting a zip code the city name doesn't show up. it says the error is that wallOfText is not a function but i'm not sure how to fix it. any help would be appreciated!! here's the code:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<meta charset="UTF-8">
<title>Example</title>
</head>
<body>
Enter your zip code:<br><input type="text" id="zipBox" name="zipCode"><br><br>
<button onclick="weatherFunction()">Submit</button>
<p id="result"></p>
<script>
function weatherFunction() {
var zip = document.getElementById("zipBox").value;
jQuery(document).ready(function ($) {
$.ajax({
url: "http://api.openweathermap.org/data/2.5/weather?zip=" +zip+ ",us&appid=b3456f9acbfa64fc4495e6696ecdc9a5",
dataType: "jsonp",
success: function (wallOfText) {
city = wallOfText("name");
if (zip != null) {
document.getElementById("result").innerHTML = wallOfText;
}
}
});
});
}
</script>
</body>
</html>
The issue you have is that you're attempting to call wallOfText like it's a function, when in fact it's the object which has been deserialised from the response of the AJAX call. As such, you need to access the object's name property to set the city variable, then use that to set the text() of the #result element.
Note that the document.ready handler within the function is redundant, and you should be doing the zip value validation before you make the request. I also updated the logic to use jQuery to bind the event handler on the button instead of the outdated onclick attribute. Try this:
jQuery(function() {
$('#send').click(function() {
var zip = $("#zipBox").val();
if (zip !== '') {
$.ajax({
url: "http://api.openweathermap.org/data/2.5/weather?zip=" + zip + ",us&appid=b3456f9acbfa64fc4495e6696ecdc9a5",
dataType: "jsonp",
success: function(wallOfText) {
var city = wallOfText.name;
$("#result").text(city);
}
});
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Enter your zip code:<br>
<input type="text" id="zipBox" name="zipCode" value="90210" /><br /><br />
<button type="button" id="send">Submit</button>
<p id="result"></p>

Knockout bindings are not updating

I'm playing around with an app that gets playlistItem data from the youtube api and lists all titles in the playlist on a page using knockout.js. I can get the list to load just fine, but I'm running into some issues while trying to add some extra functionality to the app.
Things I'm trying to add are a count of the total number of titles in the playlist and an input field that lets the user load another playlist. I currently can get neither to work.
Here's the app.js file:
// global variables
var ytResults=[];
var pageToken;
//var clipCount=ko.observable('');
var clipsDone=0;
var ytPlaylistID='PLpmQJ2D10iJx_GEYNZwAON38cluj0dNj4';
// function to create clip objects
var clip=function(data){
this.clipTitle=ko.observable(data.title);
};
function Model(){
var self=this;
//Create an observable array to store a list of clip objects
self.clipList=ko.observableArray([]);
self.clipCount=ko.observable('');
}
var model =new Model();
function ViewModel(){
var self = this;
self.errorMessage=ko.observable('');
self.loadPlaylist=ko.observable('');
errorHandling=function(){
self.errorMessage("Can't load the list and app");
};
fillList=function(){
for(i=0;i<ytResults.length;i++){
var clipData={
title: ytResults[i]
};
model.clipList.push(new clip(clipData));
};
};
var ytConnector=(function(){
var searchYtRequest=function(requestPayload, callback){
$.ajax({
url: requestPayload.url,
type: requestPayload.method,
}).done(function(data){
//console.log(data);
model.clipCount=data.pageInfo.totalResults;
ytResults.length=0;
for(i=0;i<data.items.length;i++){
ytResults=ytResults.concat(data.items[i].snippet.title);
};
fillList();
pageToken=data.nextPageToken;
clipsDone=clipsDone+50;
if(clipsDone<model.clipCount){
ytConnector.fetchDataFromYt();
};
}).fail(function(jqxhr, textStatus, error) {
// Let empty results set indicate problem with load.
// If there is no callback - there are no UI dependencies
self.errorMessage("Failed to load: " + textStatus + ", " + error);
}).always(function() {
typeof callback === 'function' && callback(ytResults);
});
};
// get playlist data from youtube
function fetchDataFromYt(){
if(pageToken!=null){
thisUrl='https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId='+ytPlaylistID+'&key=AIzaSyBFrCeUpPitoT6eOk_mq6Uza6etWtAH0oQ&pageToken='+pageToken;
}else{
thisUrl='https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId='+ytPlaylistID+'&key=AIzaSyBFrCeUpPitoT6eOk_mq6Uza6etWtAH0oQ';
};
var requestData = {
url: thisUrl,
method: 'GET',
};
searchYtRequest(requestData);
}return{
fetchDataFromYt: fetchDataFromYt,
};
})();
ytConnector.fetchDataFromYt();
thisPlaylist=function(){
ytPlaylistID=self.loadPlaylist();
console.log('playlist ID: '+ytPlaylistID);
};
}
ko.applyBindings(new ViewModel());
// PLpmQJ2D10iJzd1SPy7FlaaBFt07fhLSL3
Here's the html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Telex|Aldrich" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<title>Youtube playlist</title>
</head>
<body>
<div class="container">
<div class="errorMsg" data-bind="text: errorMessage, visible: errorMessage">
</div>
<div class="form-holder">
<form data-bind="submit: thisPlaylist">
playlist ID: <input type="text" size="50" data-bind="value: loadPlaylist, valueUpdate: 'afterkeydown'">
<button type="submit" data-bind="enable: loadPlaylist().length>0">submit</button>
</form>
</div>
<div class="info-holder">
clips in playlist:<span data-bind="text: model.clipCount"></span>
</div>
<ul class="listDiv" data-bind="foreach: model.clipList">
<li data-bind="text: clipTitle">
</ul>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="js/lib/knockout-3.2.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script src="js/oauth-1.0a.js"></script>
<script src="js/app.js"></script>
</body>
model.clipCound is an observable object, the way you are setting the value is incorrect.
model.clipCount=data.pageInfo.totalResults;
You need to change to this
model.clipCount(data.pageInfo.totalResults);

Trapping user input and using as search of Flickr API, need to get button click working

I'm trying to get the user to input a search term, and then use that term as a tag to search Flickr's API. I managed to get the basic search working, but something has gone wrong between that and adding the button click event. Can someone put me right? I feel like it's something little that I'm not seeing, I'm pretty new to jqueryand json.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script>
$("button").click(function() {
var searchTerm = $("input:text").val();
var flickrApi = "https://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
$.getJSON(flickrApi, {
tags: "searchTerm",
tagmode: "any",
format: "json"
})
.done(function(data) {
$.each(data.items, function(i, item) {
$("<img>").attr("src", item.media.m).appendTo("#images");
if (i === 3) {
return false;
}
});
});
})
</script>
</head>
<body>
<input type="text" id="search">
<button type="submit">Search</button>
<div id="images"></div>
</body>
</html>
Try removing double quotes in your variable "searchTerm" changing:
$.getJSON( flickrApi, {
tags: "searchTerm",
tagmode: "any",
format: "json"
})
to
$.getJSON( flickrApi, {
tags: searchTerm, // Local variable.
tagmode: "any",
format: "json"
})
Btw, you need to place your code inside a jQuery function. The jQuery functionality will successfully run when the DOM is ready to interact with HTML tags through jQuery/Javascript code.
$(document).ready(function()
{
// jQuery/Javascript code goes here...
});
Or the shorthand for $(document).ready():
$(function()
{
// jQuery/Javascript code goes here...
});
Demo

Backbone.js: Run and display api results on keydown event

I am programming with Backbone.js I am trying to run an API request when the user types in a query in the search box. However nothing happens when I type in a query.
Here is my JAVASCRIPT:
$(function(){
var SearchList = Backbone.Collection.extend({
url: "https://api.nutritionix.com/v1_1/search/taco?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name%2Cbrand_name%2Citem_id%2Cbrand_id&appId=26952a04&appKey=78e2b31849de080049d26dc6cf4f338c",
initialize: function(){
this.bind("reset", function(model, options){
console.log("Inside event");
console.log(model);
});
},
//** 1. Function "parse" is a Backbone function to parse the response properly
parse:function(response){
//** return the array inside response, when returning the array
//** we left to Backone populate this collection
return response.hits;
}
});
// The main view of the application
var App = Backbone.View.extend({
initialize: function () {
this.model = new SearchList();
this.list = $('#listing');
},
el: 'document',
events: {
"keydown" : "prepCollection"
},
prepCollection: function(){
var name = $('input').val();
var newUrl = "https://api.nutritionix.com/v1_1/search/" + name + "?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name%2Cbrand_name%2Citem_id%2Cbrand_id&appId=26952a04&appKey=78e2b31849de080049d26dc6cf4f338c";
this.model.set("url", newUrl);
this.model.fetch({
success: function (response, xhr) {
console.log("Inside success");
console.log(response.toJSON());
},
ERROR: function (errorResponse) {
console.log(errorResponse)
}
});
this.listenTo(this.model, 'sync', this.render);
},
render: function(){
var terms = this.model;
terms.each(function (term) {
this.list.append("<li>" + term.get('field')["brand_name"] + "</li>")
}, this);
}
});
var app = new App();
});
Here is my HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Bootstrap 101 Template</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>Interactive Food Guide</h1>
<div>
<input type="text" id="searchBox"> <br/><br/>
</div>
<ul id="listing"></ul>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Backbone and Underscore -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
<!-- apps functionality -->
<script src="js/app.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>
url is a property of the model, not an attribute. Think of attributes as things you might persist to the server.
Change:
this.model.set("url", newUrl);
To:
this.model.url = newUrl;
Note that url can also be a function which returns a string, and that there is a default function already there which works for some more typical REST cases: http://backbonejs.org/#Model-url
Also JS variables and object keys are case-sensitive, so your key should be error nor ERROR.
After running the project I noticed a couple of other things wrong:
el: 'document' - This is the whole document including the head, Backbone works with the body or things within it. Fix this by changing it to el: 'body'
You were trying to access the field attribute - it is actually called fields and you can access it like so term.get('fields').brand_name
Other bonus fixes: Clear the list before appending new results, _.throttle prepCollection so that if letters are typed fast then it will only do 2 searches (one at the beginning and one at the end of the input). Change to _.debounce to only do one search at the end of the input.
Fiddle: http://jsfiddle.net/ferahl/2nLezvmg/1/

Categories