AshFetch’em- Gotta Try and Catch’-then all!¶
Time to dive back into scary JavaScript waters! Before doing so, let
’s just make sure we are warmed-up for our swim!
Back to JavaScript variables again!¶
Lists/arrays in JavaScript¶
In JavaScript, we can store multiple values in a single variable using an array
!
An array
is a list of values separated by commas ,
and enclosed in square brackets []
.
For example, an array of numbers can look like this:
An array of strings can look like this:
Arrays can also store different types of values, like this:
Also, arrays are zero-indexed, meaning the first element is at index 0
, the second element is at index 1
, and so on.
Accessing elements in an array¶
To access an element in an array, we use the index of the element in square brackets []
.
Using the previous example:
let myArray = [1, 2, 3, 4, 5];
console.log(myArray[0]); // This will print 1
console.log(myArray[1]); // This will print 2
JavaScript Warm-up: Using Variables¶
Instead of hard coding the values, we can use variables to store the values. For example, instead of writing:
// Initialize the map
const map = new maplibregl.Map({
container: 'map', // container ID
style: 'https://api.maptiler.com/maps/streets-v2-light/style.json?key=wsyYBQjqRwKnNsZrtci1', // Your style URL
center: [-118.4430,34.0691], // Starting position [lng, lat]
zoom: 15 // Starting zoom level
});
We can write:
// Declare global variables
const centerLngLat = [-118.444, 34.070];
const startingZoomLevel = 10;
// Initialize the map
const map = new maplibregl.Map({
container: 'map', // container ID
style: 'https://api.maptiler.com/maps/streets-v2-light/style.json?key=wsyYBQjqRwKnNsZrtci1', // Your style URL
center: centerLngLat, // Starting position [lng, lat]
zoom: startingZoomLevel // Starting zoom level
});
This is a little more work, but it is much easier to reuse the values and also change them later since they are all defined at the top! For example, if we wanted to change the map center, we can just change the value of centerLngLat
instead of having to change the value in multiple places.
Finished warm-up code¶
JavaScript Objects
- Boxing-up our variables¶
An object
is a unique variable that can store many other variables! Think of it as a big box where many other Lego pieces or even other boxes can be put inside!
Your object can look like this too:
Wait! Didn’t we see this somewhere?
Yep! It was in the GeoJSON we created!
The meaning behind GeoJSON
GeoJSON actually stands for “geographic” JavaScript Object Notation!
In a JavaScript object, each value has a key
and a value
.
The :
symbol seperates the key
from the value
, like this:
- Everything in an object is contained within the curly braces
{}
- Anything to left of the
:
is the key - Anything to right of the
:
is the value - New key-value pairs are separated by a comma,
,
- Warning ! Never end an object with a
,
!!!!
Accessing an object’s property¶
To access an object
’s properties we use the .
notation.
For example, myObject.key
will return the value, which in this case is.. value
!
No spaces in variable names!
You cannot use spaces in variable definitions like let my map;
, so stick with camelCase
or snake_case
when naming varibles with multiple words. When defining key
s in objects
, you can use spaces, but it is not recommended.
If you do encounter a key
with a space in it, like, let anObject = "my annoying key": "is this"
, you cannot use the .
syntax to access it you must use this alternative method:
anObject["my annoying key"]
⚽In-class Exercise #2 - Variables and console.log¶
Tasks
- Re-copy this week’s lab template with
index.html
andinit.js
- Put the
centerLngLat
andstartingstartingZoomLevel
values into anobject
calledmapOptions
. - Use
console.log()
to get theobject
to show up in the console in Firefox.
Reminder: Working with our Dev Console
In VS Code, start Live Server by clicking Go Live
.
After Firefox runs, open the Console:
- You can either right click anywhere on a page with the mouse and clicking on
Inspect
or press F12 on the keyboard.
Remember to think of the Console as the Command Line/Terminal for your browser.
Answer
Your code should look like the following:
let mapOptions = {'centerLngLat': [-118.444,34.0709],'startingZoomLevel':5}
const map = new maplibregl.Map({
container: 'map', // container ID
style: 'https://api.maptiler.com/maps/streets-v2-light/style.json?key=wsyYBQjqRwKnNsZrtci1', // Your style URL
center: mapOptions.centerLngLat, // Starting position [lng, lat]
zoom: mapOptions.startingZoomLevel // Starting zoom level
});
-
In the console, type in
mapOptions
(or whatever you chose to name your object) then press Enter. -
You should see your JavaScript object,
mapOptions
!
Reflection
Think about the benefits of having variables in an object, is it easier to read for you? Harder?
Knowing how to check the console will help us test our JavaScript code and even run functions and methods without leaving the browser!
Wait for the map to load with map.on('load')
¶
Remember last lab where we discussed methods? Well, we can use a method called map.on('load')
to run a function when the map is loaded!
This is VERY important because we want to make sure the map is loaded before we add anything to it, such as our markers or GeoJSON data!
Here is how it looks:
Check the console¶
If you want to check if the map is loaded, you can use console.log()
to see if the map is loaded!
map.on('load', function() {
// Add your code to run after the map is loaded here
console.log("Yay! The map is loaded!")
});
Go ahead and open the console to see if the message appears!
Finished ⚽Exercise #2 code¶
Make sure your code looks like the following before moving on:
Time to fetch
and then
do something¶
To access data, we will use the JavaScript Fetch API to fetch
our GeoJSON file and then
add it to our map.
When we access the GeoJSON file with the Fetch
API we then get many methods
to use with it.
A fetch
looks like this:
fetch("map.geojson")
Wait! No variable
declaration?!
Why do you think so?
Answer
The fetch
API is actually a built-in function for JavaScript
, much like console.log()
!
Good? Let’s carry on then
!¶
fetch
actually does nothing by itself! It needs to do something with the data. Thus, fetch
is almost always used together with the then
method as follows:
fetch("map.geojson") //(1)!
.then(function aFunctionName(data){//(2)!
return data.json()//(3)!
})
.then(function anotherFunctionName(data){ //(4)!
// Do something with the data
processData(data);
});
map.geojson
is location of the GeoJSON file relative to our file. If you moved the file to a subdirectory calleddata
, then you would have to make thisdata/map.geojson
.- Here is our first chain, we are trying to
fetch
our geojson file. We will call ageneric
function in here. - For the next step we need a
json
, so wereturn
the value as ajson
with the.json()
method! - This is the next
then
i.e. our second chain! - This calls
L.geoJSON()
and adds ourdata
to the map.
Catch-ing errors
If there is an error in the fetch
or then
methods, you can use the catch
method to catch the error and do something with it.
Here is an example:
fetch("map.geojson")
.then(function aFunctionName(data){
return data.json();
})
.then(function anotherFunctionName(data){
// Do something with the data
processData(data);
});
.catch(function(error) {
console.log("An error occurred: ", error);
});
The catch
method will catch any errors that occur in the fetch
or then
methods and log them to the console.
Anoynmous functions
¶
Since our .then
is a one-time call, we can actually avoid naming the function! This is because we will not be using it again!
So we can make our function
anoymous by removing the name part of it and using the =>
symbol!
Here’s how the simpler fetch-then
should look:
fetch("map.geojson") //(1)!
.then(response => { //(2)!
return response.json();
})
.then(data =>{ //(3)!
// do something with the data
});
Looks much better, right? Well… We can shorten it even more!!!
WHAT IS THIS =>
?!!!¶
The =>
is a shortcut to define an anoynmous
function and is called an arrow-function
!
Going forward we will use the arrow-function
because it is shorter, but if you want to use the more verbose function
syntax (like function(data){}
) you can.
Putting our fetch
and then
into the map.on('load')
¶
Since we want to make sure the map is loaded before we add our GeoJSON data, we will put our fetch
and then
into the map.on('load')
method!
Here is how it looks:
map.on('load', function() {
fetch("map.geojson")
.then(response => {
return response.json();
})
.then(data =>{
// do something with the data
});
});
Create a function to processData()
¶
This function will loop through each of the data and apply various functions to it, such as adding markers or buttons. A function like this is useful as a helper
function because it can separate what we want the website to do from the immediate data processing.
Here is how it looks:
function processData(results) {
console.log(results);
}
map.on('load', function() {
fetch("map.geojson")
.then(response => {
return response.json();
})
.then(data =>{
processData(data);
});
});
Alright! Now the stage is set to talk about for-loops
and arrays
!
🏁Checkpoint¶
- You should have a
map.geojson
file in the same directory as yourindex.html
andinit.js
files. - You should have a
map.on('load')
method thatfetch
es themap.geojson
file andthen
calls aprocessData
function.
Before moving on, check to see if JavaScript code looks like the following: