Hello.
In this video, I'm going to look at how
you query an API continuously while a program is running,
a program that's perhaps animating something.
And that animation doesn't stop.
It continues smoothly but updates
whenever new data comes in.
Boy, isn't that an exciting topic?
You woke up this morning and thought,
I want to watch a video about how
you query an API continuously while an animation is
happening, right?
That's what I woke up thinking I was going to do,
is make a video about that.
Actually, I just thought of this a few minutes ago,
so I didn't really wake up thinking about it.
But let's just get started.
So this, by the way, is a program
that I've set up in advance just to have a simple animation
on the screen.
Nothing too exciting.
There's a line that's moving across.
There's a single variable for the line.
The line is incrementing by 5 pixels When it gets to the end,
it starts back at 0.
So we can see there's an animation.
Now what I need to demonstrate this idea is
I need an API that's going to give me data,
and it's going to give me different data every time
I query it.
So a lot of APIs don't really do this.
For example, if you asked for the weather,
you're going to get the temperature outside.
The temperature outside obviously is changing
but the weather API probably isn't going
to update every few minutes.
If you ask for the New York Times to do an article search,
there's not going to be a lot of new articles
with a certain word every few seconds.
However, there is this API that's on open-notify.org
and it gives you the International Space Station
current location.
And, by the way, in case you were wondering,
that's changing.
It's moving.
The Earth is spinning--
I don't know.
Somehow it all works-- physics.
Ask Stephen Hawking.
I don't know about this stuff, although I find it fascinating.
So what we can look for here is, look,
here is how-- here is the URL for getting
JSON data with the latitude and longitude of the International
Space Station.
So all I need is this particular URL.
I'm going to copy it.
I'll put it in the web browser to look at that data.
And we can see, there it is.
The International Space Station position
is currently at this particular latitude
and this particular longitude.
Hit refresh.
Oh, come on, change.
It changed, right?
You can see it's changing each time I hit refresh.
A little bit, but changing.
Oh, it's moving by a fast latitude.
This is like a-- this is called the refresh dance, by the way.
It's good-- physical exercise is important.
While I'm standing and making these videos,
I feel like I need to move around more.
So when you practice APIs, move around.
Where was I?
So this is some stuff that I want to get into the program.
So, first, let's just get started with that.
So the first thing I want to do is grab this URL now.
And inside the program, maybe just in setup right now,
I'm going to say loadJSON.
And I'm going to say the URL is--
for this particular API.
And let's just make this a global variable.
I'm trying to make things that fit in my code nicely.
var url equals-- ah.
Bad copy-paste job.
Paste that in there.
So that's the URL for the API query.
Let's make this a little bit wider.
So now I want to load JSON.
I'm using the p5 loadJSON function,
which says give me a URL.
It doesn't say anything, actually.
But the thing you can give to it is a URL
where you can get some JSON.
And then a callback.
So I'm going to call the callback gotData.
So this function will be executed
when the data has come back.
So I'm going to say function and I'm
going to write that function, gotData.
The argument, the parameter of that function,
which I happen to be calling data-- you can call it anything
you want, like a manatee.
The parameter data is what's going
to get filled with the JSON that's coming from that URL.
So, just quickly, if I just said println data,
we'd be able to see very easily that--
whoops.
Ah.
So remember this thing?
I talked about this in a previous video.
Boy, I hope this works.
Sometimes it doesn't work.
Sometimes it doesn't work because of security issues with
how information is passed between different servers,
and open-notify.org is a different server.
And if you just add some padding--
so this thing called JSONP.
If you add a third argument, jsonp--
maybe someday I'll make a video of just what is this JSON
thing.
It's telling p5 behind the scenes
to use this other way of getting the data that kind of passes
security.
So, hopefully, now, when I run this sketch, we can see.
And there it is.
Now you can see the data showed up down here in the console.
I've got that data.
So looking at this, remember, the next thing
that we need to do is figure out how do I get the latitude,
how do I get the longitude?
Well, JavaScript Object Notation is the way that I do this.
This whole thing is an object.
And I want to get the first property, iss_position.
And then I want to get the first property of iss_position,
latitude.
I want to get the second property of iss_position,
longitude.
And, by the way, I said first and second.
In objects, the order doesn't actually matter.
It's not like an array where you would
be referencing from the index.
You'd be-- you-- you be--
I'll be-- I am.
I don't know what tense I'm in any more--
present, past, future perfect, something like that.
But I'm going to, in a moment, on the computer,
type in data.iss_position.latitude.
That's how I traverse into this JSON data.
So back here, I'm now going to say,
just to make sure this is working,
println data.iss_position.latitude.
What rhymes with latitude?
Fortitude?
I don't know.
And you can see, there it is.
Beautiful.
So let's think about what I might do now.
Hmm.
With that data, what might I do?
Well, let's say I want to draw the space
station on the screen.
And my space station again, from the person
with no visual talents, will be a circle.
So let's make a variable called issX, issY,
because I want to make variables that
are impossible to pronounce.
And in gotData, I'm just going to say issX equals the latitude
and issY equals the--
say it with me now.
I feel like I'm Mr. Rogers--
longitude.
Can you say longitude?
It would be an--
yes, that's a good thing to aspire, to be Mr. Rogers.
So I can put those in those variables.
And let's give those variables some default
values just to start.
And then, let's, in our program--
I feel like this belongs to you and me, this program.
So I could say our program--
I'm going to draw the International Space Station.
And now I'm going to say fill 255.
Here we go.
And where is it?
Hmm.
I don't see that International Space Station.
Why don't I see that International Space Station?
What data am I getting?
50, negative 95.
Well, if I draw something at the pixel x equals 50
and the pixel y equals negative 95, that's where?
50 over.
That's way off the screen.
So this brings up an interesting question.
I have a latitude and longitude.
That's real world measurement data
of where the ISS actually is above the Earth in the units
latitude and longitude.
But this thing that I'm drawing in the window is pixels.
It's two-dimensional.
It's got an x-axis, it's got a y-axis, 0, 0
at the top left corner.
So I somehow need to translate latitude and longitude
to x and y.
Now, a topic for another video might be how to do that using,
quote-unquote, "correct"-- and I won't use air quotes here,
but, quote-unquote, "correct math."
if you take a spear and you flatten it out,
you need to do some sort of spherical transformation
of those spherical coordinates to where
they are in a 2D plane.
But, you know, sometimes in life that's too complicated.
I don't want to worry about that right now.
It hurts.
I have a pain that's like-- it's in my lower back right now.
And I just want to live an easy and friendly life.
And the way that we could do that
is just with the map function.
Because latitude has a range between negative 90 and 90.
And longitude has a range between negative 180 and 180.
Which one is it?
Well, it's got-- one of these was negative 95.
I was right about that.
So I could just take those ranges
and map them from 0 to pixel width, from 0 to pixel height.
So let's do that.
So what I really want to do is I'm
going to say var lat equals the latitude,
var long equals the longitude.
And then issX equals map the latitude,
which goes from negative 90 to 90, to between 0 and width.
So, if you recall, I definitely have a video somewhere all just
about this map function.
What the map function does is it takes
a value that has a given range and maps
that value to another range.
By the way, you could do that math yourself if you wanted to.
I know you guys.
I believe in you.
It's not that complicated, but it's
nice to have the map function to handle that for you.
And I think perhaps in my other video
I talk about what the math behind the map function is.
So now, if we run this--
look, there it is, the International Space Station.
And if I hit refresh--
come on, move.
You can see it's moving a little bit, very ever so
slowly and slightly.
So I probably could do a better job
of making this appear more individually interesting,
but we've got something working here.
But I've spent all this time--
I've been talking for 9 and 1/2 minutes and I haven't even
gotten to--
this is just all setup, all setup for the real tofu.
I don't want to say meat because it sounds weird--
the real essence of this video.
Which is now-- all I did was query that
URL at the beginning in setup and I got the data once.
I want to just keep getting that data over and over again.
How do I do that?
So there's a couple of possibilities here
of how you could do that.
One thing is I have this draw loop.
draw, remember, is looping over and over again
for the purpose of the animation.
So I could figure out a way to just put
the loadJSON function in draw.
That would be querying the API 60 times per second.
Now, that's probably way too often.
So another way I could do it is use some kind of counter
and say, like every 10 times through draw,
or every 30 times, or every 100 times, query the API.
All of those are possible and I encourage
you to try doing that on your own as an exercise.
Or put something in the comments that
say, hey, give a link to some code that does that.
I'll be glad to do that.
But what I want to demonstrate to you in this video
is another way of doing it.
And I will shuffle off to Buffalo over here.
Buffalo.
And I'm going to do this with a function called setTimeout.
And even better yet, I think maybe I'll
actually do it with a function called setInterval.
These are functions that are part of JavaScript itself
in the browser.
These are not p5 functions.
And what these functions do, setTimeout
says trigger an event once at blank time.
So setTimeout says, I want you to do this event
and I want you to do it 3 seconds from now.
setInterval is very similar.
Trigger an event over and over every blank time,
every blank milliseconds.
Time should really say milliseconds.
At blank milliseconds, at blank milliseconds.
So the difference is--
the event is clap.
I'm going to say the event is clap.
So if I say setTimeout 3,000, what's going to happen is--
1 1,000, 2 1,000, 3, 1000.
If I say setInterval 3,000, what's going to happen is--
1 1,000, 2 1,000, 3 1,000, 1 1,000, 2 1,000, 3 1,000,
1 1,000, 2 1,000, 3 1,000.
It's going to do that at the same interval over and over
again.
So you can ask yourself, which one
is the one you want for this program?
I want to ask for the data every so often.
So I can use setInterval.
Now, there's some nuance to this.
There's some reasons why in other scenarios
I'd want to use setTimeout.
And once I get the data back, just ask for it again.
That actually could be a good way of doing this.
But setInterval is going to be easiest for us right now.
So the way that these functions work
is, if I'm using setInterval, for example, setInterval--
and then I'm going to pass in a callback.
This is the function name of the thing
that I want to happen every blank milliseconds.
So all I need to do is say, setInterval, do
this thing every so often.
Let's look at that over here now.
So in setup-- I want this to start in setup.
I want to say setInterval askISS every--
what should we do?
Let's just do every second.
So 1,000.
So this now-- whoops.
This line of code says execute some function called askISS
every 1,000 milliseconds.
And the magic of JavaScript and asynchronous events
is I can set that thing up going and it's
going to happen on its own, but draw down here
will also continue.
So this animation will continue.
The API calls will be happening.
When the data's writing, the gotData function will happen.
That whole how the order of everything will happen
will be managed by the magic of JavaScript
event-based handling.
So all I need to do is set up the events.
I need to say, set up this interval
and then also do draw at the same time, which is
what I'm doing in this program.
So now, what goes in this function called askISS?
This loadJSON call.
So I just want to do exactly this loadJSON
call every 1,000 seconds for the rest of time,
at least while the program is running.
And we can run this now.
And you can see, there it is.
Come on, move, dot, move.
ISS, get some speed going.
So one thing that I might do, actually, here
is change my mapping.
This mapping is I was mapping the full latitude, longitude
of the entire world.
But we can see here that it's currently at latitude 47
and currently at longitude negative 54.
So let's go between 45 and 50, and negative 55 and 50.
So if I change this to be between 45 and 50,
and-- what did I say?
Negative 55 and negative 50.
I think if I do that, we're going to get some-- oh, look.
There it is.
It's moving.
Can you see the space station?
The space station is flying every second.
Now, you can see it has a rhythm to it because I'm
querying it every second.
What I would love to do with this but I've been kind
of-- this video is approaching 15 minutes--
is I would love to add a little easing motion into it
so it doesn't just jump to the next spot
when it gets a new spot.
It sort of smoothly moves and you can
make it feel like it's moving.
I'd also love to put an actual map there.
I'd love to do the correct spherical maths.
I said maths again without even thinking about it.
Usually, I do that just because I like saying maths.
Oh, it's leaving.
Goodbye, International Space Station.
So, anyway, but I'll leave that as a review exercise
for you guys.
So what I would say is give this a try.
Like build exactly the same thing.
What happens if you do it every 10
milliseconds versus every 3,000 milliseconds?
Could you make it move, interpolate between those two
locations?
I can't-- I'm trying to think of other exercises that you could
do.
But play around with it.
I'm sure you can be creative and come up with some ideas.
And hopefully this video helped you learn something today.
I don't have anything like, say, [INAUDIBLE],,
although I think I say [INAUDIBLE]
at the end of every video now.
OK, goodbye.
Broken-- sleeping mouse.
Hashtag sleeping mouse.
You could say that.
If you watched this video, tweet me hashtag sleeping mouse.
[INAUDIBLE] sleeping-- I don't know.
How am I going to keep track?
I'm not going to build a search for these things?
Never mind.