Junior dev here:
Goal: I would like to define my global variable [array of objects] in one JS file (globalVariables.js) and dynamically access that global variable's key values from different JS (index.js, products.js) and HTML (index.html, products.html, etc.) pages. I will include all of these pages at the bottom.
Essentially, on both index.html and products.html, I am listing my client's products, and the global variable is supposed to fill in all that information dynamically.
According to W3schools section on Global Variables, I should be able to declare the variable like so:
var carName = "Volvo";
and access it like so:
console.log(window.carName)
Unexpected Result: Instead, nothing shows up in the browser and, looking at the console, I read:
jQuery.Deferred exception: Cannot read property '0' of undefined TypeError: Cannot read property '0' of undefined
at HTMLDocument.<anonymous> (https://tiegrrr.com/testing/js/index.js:19:54)
at e (https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js:2:30005)
at t (https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js:2:30307) undefined
Furthermore, if I try defining the global variable like I've seen recommend on some websites...
var window.allProducts = [object, object, object, etc.]
...I get a different error in VS Code:
',' expected.ts(1005)
What am I missing? And why would it work locally but not online, given the directory structure is the same?
==================================================
ALL THE FILES
globalVariables.js
var allProducts = [
{
name: 'TieGrrr Strap',
img: 'tiegrrr-strap.jpg',
desc: "TieGrrr Straps are the safest alternative to stretch and bungee cords. They quickly and securely hold cargo of almost any shape or size. Works great with ladder racks, pipe, lumber, kayaks, rafts, etc.",
popularity:1,
lengths: [3,6,9,12],
colors: ["red","blue","orange","green"],
breakStrengths: ["1,200 lbs"],
cost: 5,
tag:"tiegrrr",
page: "tiegrrr-strap.html"
},
{
name: 'Ratchet Strap',
img: 'Ratchet-S-Hook.jpg',
desc: '',
popularity:2,
lengths: [6,10,12,16],
colors: ["red","blue","orange","green"],
breakStrengths: ['1,500 lb.'],
cost: 8,
tag:"ratchet",
page: "ratchet-strap.html"
},
{
name: 'Heavy Duty Ratchet',
img: 'heavy-duty-strap.jpg',
desc: '',
popularity:3,
lengths: [6,10,12,16],
colors: ["red","blue","orange","green"],
breakStrengths: ['1,500 lb.','3,000 lb.'],
cost: 10,
tag:"heavy",
page: "heavy-duty-ratchet.html"
},
{
name: 'Load Hugger',
img: 'load-hugger.jpg',
desc: '',
popularity:4,
lengths: [6,10,12,16],
colors: ["red","blue","orange","green"],
breakStrengths: ['1,500 lb.'],
cost: 15,
tag:"hugger",
page: "load-hugger.html"
},
{
name: 'Super Duty Ratchet',
img: 'SD Ratchet-F-Hook.jpg',
desc: '',
popularity:0,
lengths: [6,10,12,16],
colors: ["red","blue","orange","green"],
breakStrengths: ['1,500 lb.'],
cost: 12,
tag:"super",
page: "super-duty-ratchet.html"
},
{
name: 'Winch Strap',
img: 'winch-green.jpg',
desc: '',
popularity:0,
lengths: [6,10,12,16],
colors: ["red","blue","orange","green"],
breakStrengths: ['1,500 lb.'],
cost: 9,
tag:"winch",
page: "winch-strap.html"
},
{
name: 'Universal Cam Strap',
img: 'universal-strap1.jpg',
desc: '',
popularity:0,
lengths: [6,10,12,16],
colors: ["red","blue","orange","green"],
breakStrengths: ['1,500 lb.'],
cost: 6,
tag:"uni",
page: "universal-cam-strap.html"
},
{
name: 'Endless Ratchet',
img: 'endless-ratchet-strap.jpg',
desc: '',
popularity:0,
lengths: [6,10,12,16],
colors: ["red","blue","orange","green"],
breakStrengths: ['1,500 lb.'],
cost: 8,
tag:"endless",
page: "endless-ratchet-strap.html"
}
];
indes.js
$(() => {
let $container = $('#item-container')
// TODO: make it so LOOP automatically filters for 1-4
for (i=0;i<4;i++) { // LOOPS through first 4
$newITEM_div = $('<div>') // PARENT div for ITEM + IMG
$newITEM_div.addClass("item")
$newITEM_NAME_div = $('<div>') // div for ITEM NAME
$newITEM_NAME_div.text(window.allProducts[i].name)
$newITEM_NAME_div.addClass("item-name")
$newITEM_IMG = $('<img>')
$newITEM_IMG.css("background-image", `url('../testing/images/${window.allProducts[i].img}')`);
$newITEM_div.append($newITEM_NAME_div)
$newITEM_div.append($newITEM_IMG)
$newITEM_div.attr('onclick',`location.href='./products/${window.allProducts[i].page}'`);
$container.append($newITEM_div)
}
})
console.log(window.allProducts)
products.js
$(() => {
let $container = $('#item-container')
// splits string at every "/" then POPS last array element
var currentPage = $(location).attr('href').split("/").pop();
// TODO: make it so LOOP automatically filters for 1-4 popularity
// on PRODUCTS page, this code loops through ALL PRODUCTS for category imgs
if (currentPage.match("products.html")) {
for (i=0;i<window.allProducts.length;i++) {
$newITEM_div = $('<div>') // PARENT div for ITEM + IMG
$newITEM_div.addClass("product-item")
$newITEM_NAME_div = $('<div>') // div for ITEM NAME
$newITEM_NAME_div.text(window.allProducts[i].name)
$newITEM_NAME_div.addClass("product-item-name")
$newITEM_IMG = $('<img>')
if (currentPage.match("products.html")) {
$newITEM_IMG.css("background-image", `url('../testing/images/${window.allProducts[i].img}')`);
} else {
$newITEM_IMG.css("background-image", `url('../images/${window.allProducts[i].img}')`);
}
$newITEM_div.append($newITEM_NAME_div)
$newITEM_div.append($newITEM_IMG)
$newITEM_div.attr('onclick',`location.href='./products/${window.allProducts[i].page}'`);
$container.append($newITEM_div)
$container.removeAttr('id');
$container.addClass("all-products-container")
}
} else {
for (i=0;i<window.allProducts.length;i++) {
if (currentPage.includes(window.allProducts[i].tag)) {
let currentProduct = window.allProducts[i]
let $productImg = currentProduct.img;
let $productTitle = currentProduct.name;
let $productDesc = currentProduct.desc;
let $productCost = currentProduct.cost;
$("#product-image").attr("src",`../images/`+$productImg);
$('h1').text($productTitle);
$('#description').text($productDesc);
for (i=0;i<currentProduct.lengths.length;i++) { // LOOPS through first 4
$newLength = currentProduct.lengths[i]
$newLength_div = $('<div>')
$newLength_div.text($newLength)
$newLength_div.addClass("length")
$('.lengths').append($newLength_div)
}
for (i=0;i<currentProduct.colors.length;i++) { // LOOPS through first 4
$newColor = currentProduct.colors[i]
$newColor_div = $('<div>')
$newColor_div.addClass("color")
$newColor_div.css("background-color",`${$newColor}`)
$('.colors').append($newColor_div)
}
for (i=0;i<currentProduct.breakStrengths.length;i++) { // LOOPS through first 4
$newBreak = currentProduct.breakStrengths[i];
if (i>0) {
$('#breaks').append(`, `+$newBreak);
} else {
$('#breaks').text($newBreak);
}
}
$('#cost').text(`$`+$productCost+`.00`);
break;
} else {
continue;
}
}
}
})
index.html (head and body, StackOverflow didn't like the full doc for some reason)
<head>
<title>TieGrrr Straps, Inc.</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="TieGrrr Straps, Inc.">
<meta name="description" content="Manufacturers of high quality tie-down systems at competitive prices.">
<meta name="keywords" content="tie downs, tie-downs, tie down straps, ratchet straps, straps, tie downs, tie down systems, tie down manufacturers">
<!-- BOOTSTRAP CSS -->
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<!-- TieGrrr Strap CSS -->
<link rel="stylesheet" type="text/css" href="css/styles.css">
<!-- add GOOGLE FONTS here-->
<link href="" rel="stylesheet"> <!-- ADD Google Font when ready-->
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- BOOTSTRAP JS -->
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<!-- SLICK carousel -->
<link rel="stylesheet" type="text/css" href="js/slick-1.8.1/slick/slick.css"/>
<!-- Add the new slick-theme.css if you want the default styling -->
<link rel="stylesheet" type="text/css" href="js/slick-1.8.1/slick/slick-theme.css"/>
<!-- JS for INDEX PAGE -->
<script src="js/globalVariables.js"></script>
<script src="js/index.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div id="top-thin-bar" class="col">800.810.8881 | sales#tiegrrr.com</div>
</div>
</div>
<nav class="navbar sticky-top">
<div id="main-logo" onclick="location.href='https\://tiegrrr.com'"></div>
<div id="nav-info-content">
<div id="main-logo-mobile" onclick="location.href='https\://tiegrrr.com'"></div>
<div id="company-title">TieGrrr Straps, Inc.</div>
<div id="subtitle">Manufacturers of Quality Tie-Down Systems</div>
<div id="buttons">
<div class="active" onclick="location.href='./index.html'">HOME</div>
<div onclick="location.href='./products.html'">PRODUCTS</div>
<div onclick="location.href='./about-us.html'">ABOUT US</div>
<div onclick="location.href='./contact-us.html'">CONTACT</div>
</div>
</div>
<div id="buttons-mobile"> <!-- starts out HIDDEN -->
<div onclick="location.href='./index.html'">HOME</div>
<div onclick="location.href='./products.html'">PRODUCTS</div>
<div onclick="location.href='./about-us.html'">ABOUT US</div>
<div onclick="location.href='./contact-us.html'">CONTACT</div>
</div>
</nav>
<div class="container-fluid">
<div class="row" id="landing-carousel">
<div id="carousel-container" class="col">
<div id="carousel-inner">
<!-- CHANGE which PICS in STYLES.CSS -- look for #on-sale-item- -->
<div id="on-sale-item-1"></div>
<div id="on-sale-item-2"></div>
<div id="on-sale-item-3"></div>
<div id="on-sale-item-1"></div>
<div id="on-sale-item-2"></div>
<div id="on-sale-item-3"></div>
<div id="on-sale-item-1"></div>
<div id="on-sale-item-2"></div>
<div id="on-sale-item-3"></div>
<div id="on-sale-item-1"></div>
<div id="on-sale-item-2"></div>
<div id="on-sale-item-3"></div>
<div id="on-sale-item-1"></div>
<div id="on-sale-item-2"></div>
<div id="on-sale-item-3"></div>
<div id="on-sale-item-1"></div>
<div id="on-sale-item-2"></div>
<div id="on-sale-item-3"></div>
<div id="on-sale-item-1"></div>
<div id="on-sale-item-2"></div>
<div id="on-sale-item-3"></div>
<div id="on-sale-item-1"></div>
<div id="on-sale-item-2"></div>
<div id="on-sale-item-3"></div>
<div id="on-sale-item-1"></div>
<div id="on-sale-item-2"></div>
<div id="on-sale-item-3"></div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col text-center" id="page-content">
<div id="item-container"> <!-- use JAVASCRIPT to LOOP through -->
<!-- index.js fills in with TOP 4 POPULAR ITEMS -->
</div>
View ALL PRODUCTS
<p style="color:white; font-size:x-large; font-style:italic; font-weight:800;">GET A GRIP</p>
<p style="color:white; font-size:1.2em; font-weight:600;">We are a family-owned manufacturing company that aims to provide tie-down systems both superior in quality and price to that of any similar products carried by "big-box" stores.</p>
<p style="color:white; font-size:1em;margin-bottom:3vh;">All of our products meet or exceed both D.O.T. and Web &Sling Assoc. standards for safety. Before we will sell any product, it must pass our field and/or lab test for "normal" abuse. Our products may cost as much as other disposable tie-downs, but they will outlast even the most expensive straps.</p>
<p style="color:red; font-size:large; font-style:italic; font-weight:800;">AMERICAN OWNED</p>
<img id="USAflag" src="./images/USA.jpg">
</div>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col" id="footer">
Copyright © 2007 Tiegrrr Straps, Inc.
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script type="text/javascript" src="js/slick-1.8.1/slick/slick.min.js"></script>
<!-- SLICK carousel inline script -->
<script type="text/javascript">
$('#carousel-inner').slick({
slidesToShow: 1,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 8000,
});
</script>
</body>
products.html
<head>
<title>TieGrrr Straps, Inc. - Products</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="TieGrrr Straps, Inc.">
<meta name="description" content="Manufacturers of high quality tie-down systems at competitive prices.">
<meta name="keywords" content="tie downs, tie-downs, tie down straps, ratchet straps, straps, tie downs, tie down systems, tie down manufacturers">
<!-- BOOTSTRAP CSS -->
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<!-- TieGrrr Strap CSS -->
<link rel="stylesheet" type="text/css" href="css/styles.css">
<!-- add GOOGLE FONTS here-->
<link href="" rel="stylesheet"> <!-- ADD Google Font when ready-->
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- BOOTSTRAP JS -->
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<!-- JS for PRODUCTS PAGE -->
<script src="js/globalVariables.js"></script>
<script src="js/products.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div id="top-thin-bar" class="col">800.810.8881 | sales#tiegrrr.com</div>
</div>
</div>
<nav class="navbar sticky-top">
<div id="main-logo" onclick="location.href='https\://tiegrrr.com'"></div>
<div id="nav-info-content">
<div id="main-logo-mobile" onclick="location.href='https\://tiegrrr.com'"></div>
<div id="company-title">TieGrrr Straps, Inc.</div>
<div id="subtitle">Manufacturers of Quality Tie-Down Systems</div>
<div id="buttons">
<div onclick="location.href='./index.html'">HOME</div>
<div class="active" onclick="location.href='./products.html'">PRODUCTS</div>
<div onclick="location.href='./about-us.html'">ABOUT US</div>
<div onclick="location.href='./contact-us.html'">CONTACT</div>
</div>
</div>
<div id="buttons-mobile"> <!-- starts out HIDDEN -->
<div onclick="location.href='./index.html'">HOME</div>
<div onclick="location.href='./products.html'">PRODUCTS</div>
<div onclick="location.href='./about-us.html'">ABOUT US</div>
<div onclick="location.href='./contact-us.html'">CONTACT</div>
</div>
</nav>
<div class="container-fluid">
<!-- TODO: remove FLEX STYLES from ROW -->
<div class="row">
<div id="carousel-container" class="col">
<div id="item-container">
<!-- PRODUCTS JS fills in -->
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col text-center" id="page-content">
<div style="margin-top: 2.5vh;">
<p style="color:white; font-size:x-large; font-style:italic; font-weight:800;">GET A GRIP</p>
<p style="color:white; font-size:1.2em; font-weight:600;">We are a family-owned manufacturing company that aims to provide tie-down systems both superior in quality and price to that of any similar products carried by "big-box" stores.</p>
<p style="color:white; font-size:1em;margin-bottom:3vh;">All of our products meet or exceed both D.O.T. and Web &Sling Assoc. standards for safety. Before we will sell any product, it must pass our field and/or lab test for "normal" abuse. Our products may cost as much as other disposable tie-downs, but they will outlast even the most expensive straps.</p>
<p style="color:red; font-size:large; font-style:italic; font-weight:800;">AMERICAN OWNED</p>
<img id="USAflag" src="./images/USA.jpg">
</div>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col" id="footer">
Copyright © 2007 Tiegrrr Straps, Inc.
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
</body>
UPDATE: I incorrectly called allProducts an object when I first posted, but it's actually an array of objects, if that matters.
When you're adding something to the window it's usually best to do it explicitly.
So your second solution was probably right but your syntax was wrong, try this:
window.allProducts = {objectValues, objectValues, etc.}
Without the var. You only need to use var when creating the variable, since window already exists it'll error if you try and create it.
i'm trying to list my image preuploader sort by name but got some issues.i have dozen image with name img001 - img100 but when i input that the result show the files sort by image size. here is my code
<html>
<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 rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<title>generate nama ikan</title>
</head>
<body>
<div class="flex-center position-ref full-height">
<div class="container">
<div class="row">
<div class="col-md-12">
<h1>Nama Ikan</h1>
<input id="ingambar" type="file" multiple />
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="content">
<br />
<table class="table">
<thead>
<th>gambar</th><th>nama</th>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script>
$('#ingambar').change(function () {
for (var i=0, len = this.files.length; i < len; i++) {
(function (j, self) {
var reader = new FileReader()
reader.onload = function (e) {
$('tbody').append('<tr><td><img width="100px" src="' + e.target.result + '"></td><input class="form-control" type="text" value="' + self.files[j].name.slice(0, -4) + '" name="namaikan[]" disabled/></td></tr>')
}
reader.readAsDataURL(self.files[j])
})(i, this);
}
});
</script>
</html>
can someone show me how to get it done ?
To achieve this you can sort() the table rows after you append a new one, based on the value of the input contained within the row. Try this:
$('#ingambar').change(function() {
for (var i = 0, len = this.files.length; i < len; i++) {
(function(j, self) {
var reader = new FileReader()
reader.onload = function(e) {
$('tbody').append('<tr><td><img width="100px" src="' + e.target.result + '"></td><td><input class="form-control" type="text" value="' + self.files[j].name.slice(0, -4) + '" name="namaikan[]" disabled/></td></tr>');
sortFiles();
}
reader.readAsDataURL(self.files[j])
})(i, this);
}
});
function sortFiles() {
$('.table tbody tr').sort(function(a, b) {
var $a = $(a).find('input'),
$b = $(b).find('input');
return $a.val().localeCompare($b.val());
}).appendTo('.table tbody');
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div class="flex-center position-ref full-height">
<div class="container">
<div class="row">
<div class="col-md-12">
<h1>Nama Ikan</h1>
<input id="ingambar" type="file" multiple />
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="content">
<br />
<table class="table">
<thead>
<th>gambar</th>
<th>nama</th>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
Instead of displaying the images as you read them, you could instead put them all i an array with the same for loop. Then sort the new array with a sort function. And then you just run through the array and display them. Works for me!
You can sort using javascripts Array build in function using a custom sort function with localeCompare. Inserting the following right before the for-loop should do what you want.
this.files.sort((fileA, fileB) => fileA.name.localeCompare(fileB.name));
Providing that this.files is an array of files having a name attribute.
I get "Cannot read property '0' of undefined" error. I couldn't find the issue. I think javascript file has a problem but I couldn't see. I wrote the script twice but still js file has a problem.
HTML File
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>FreeCodeCamp - Local Weather</title>
<script src="https://code.jquery.com/jquery-3.0.0.js"></script>
<script type="text/javascript" src="app.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<div id="main" class="text-center container">
<h1>FreeCodeCamp - Weather App</h1>
<div class="row" id="fade">
<div style="margin-top: 200px;">
<span id="city"></span>
<span id="country"></span>
<div id="weather"><img id="w-icon"><span id="temp"></span></div>
<span id="description"></span>
</div>
</div>
<div id="author">
<span> Created by Kaan Karaca</span><br>
<span>#GitHub </span><br>
<span>#FreeCodeCamp </span>
</div>
</div>
</body>
</html>
JavaScript File
$(document).ready(function () {
var cityId;
var city;
var unitsFormat = "metric";
var getWeatherInfo = function () {
$.getJSON("http://api.sypexgeo.net/json")
.done(function (locationData) {
cityId = locationData.city.id;
cityName = locationData.country.iso;
$.getJSON("http://api.openweathermap.org/data/2.5/weather?", {
id: cityId,
units: unitsFormat,
APPID: '610ae7b6406da76bb34ad4bb95cc3673'
})
.done(function (weatherDate) {
$("#w-icon").attr("src", "http://openweathermap.org/img/w/" + weatherDate.weather[0].icon + ".png");
$("#temp").text(Math.round(weatherDate.main.temp) + "°C");
$("#city").text(weatherDate.name + ",");
$("#country").text(cityName);
$("#description").text(weatherDate.weather[0].description);
});
});
}
getWeatherInfo();
});
Your code is too trusting that all these calls will work.
In my case, the json from http://api.sypexgeo.net/json correctly locates me, but http://api.openweathermap.org/data/2.5/weather?" has no clue about that city id. Therefore it passes back a json such as:
{
"cod": "404",
"message": "Error: Not found city"
}
This obviously lacks the array weather, so js throws an undefined.
The solution would be to get the specs from the weather api (and location, while you're at it) and check that the response code is good. (I guessed "200" is good. I never got the success case).
$(document).ready(function() {
var cityId;
var city;
var unitsFormat = "metric";
var getWeatherInfo = function() {
$.getJSON("http://api.sypexgeo.net/json")
.done(function(locationData) {
cityId = locationData.city.id;
cityName = locationData.country.iso;
$.getJSON("http://api.openweathermap.org/data/2.5/weather?", {
id: cityId,
units: unitsFormat,
APPID: '610ae7b6406da76bb34ad4bb95cc3673'
})
.done(function(weatherDate) {
if (weatherDate.cod != "200") {
console.log(weatherDate);
console.log("Couldn't find the weather!!!");
return;
}
$("#w-icon").attr("src", "http://openweathermap.org/img/w/" + weatherDate.weather[0].icon + ".png");
$("#temp").text(Math.round(weatherDate.main.temp) + "°C");
$("#city").text(weatherDate.name + ",");
$("#country").text(cityName);
$("#description").text(weatherDate.weather[0].description);
});
});
}
getWeatherInfo();
});
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>FreeCodeCamp - Local Weather</title>
<script src="//code.jquery.com/jquery-3.0.0.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="main" class="text-center container">
<h1>FreeCodeCamp - Weather App</h1>
<div class="row" id="fade">
<div style="margin-top: 200px;">
<span id="city"></span>
<span id="country"></span>
<div id="weather">
<img id="w-icon"><span id="temp"></span>
</div>
<span id="description"></span>
</div>
</div>
<div id="author">
<span> Created by Kaan Karaca</span>
<br>
<span>#GitHub </span>
<br>
<span>#FreeCodeCamp </span>
</div>
</div>
</body>
</html>