Check out a free preview of the full Ember Octane Fundamentals course

The "Making API Calls" Lesson is part of the full, Ember Octane Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Mike demonstrates how to use fetch to gather data from the API, iterates over channel data for teams to build the channel list, and explains best practices for reaching across models.

Preview
Close

Transcript from the "Making API Calls" Lesson

[00:00:00]
>> Mike North: So let's take care of it. Import, fetch from fetch. And here we've got a team ID we're gonna say resp = await, fetch. We gotta make this an A sync function so that we may await.
>> Mike North: api/teams${teamId} just like that, right? Drop the team ID in the correct place.

[00:00:30]
>> Mike North: And decode the body to json.
>> Mike North: Sorry, responsive design, that's why we were not seeing the side bar. Two more teams had popped up. That is a pretty convincing indicator that there is certainly more data there than what we were seeing before. Now let's try clicking on one of these.

[00:00:59]
>> Mike North: All right, so now, the team is being loaded. And there is a second API call being made down here. You can click on that and you could see here is the API response coming back. And it looks like there are channels in that team, so let's iterate over those channels to build up the channel list, right?

[00:01:21]
We've already passed the whole team to that sidebar component, this shouldn't be too bad. So let's go team-sidebar.hps and what looks like a channel here, channels, okay, so it's coming up. This looks like it. That link certainly looks like what we would expect the channel to be. Data channel ID that I'm 99% sure at this point.

[00:01:47]
So let's give it a shot, each team channels as channel, there's our little array .for each and we need a link too. Instead of the a tag, right? Our route name,
>> Mike North: Is team channel. This is the innermost area in here. And channel ID, we can swap that in.

[00:02:25]
We need to provide so that we're getting an error message right now. The next thing we're gonna do is address that. You attempted to generate a link for this route, but you did not pass the models for generating its dynamic segments. I love these error messages like there.

[00:02:43]
This is actionable, right? Gotta pass the model.
>> Mike North: Model, and will be the channel ID. And then we should save, error message goes away. We should put the channel.name here.
>> Mike North: All right, that is not general, that says top secret. And if we go from team to team,

[00:03:13]
>> Mike North: Looks like we've got different channels showing up. Now, this looks weird. From using Slack before I usually expect there to be a bar on the currently active channel, right? That background highlighting. And it looks like we always get this. So I'm just gonna search through the CSS applied to this, the classes, and see if I can find something that looks like a background color.

[00:03:41]
That looks like it. What we want is a conditionally applied class if this links happens to be the active link. And Link2 has something for this, active class.
>> Mike North: PGTL dark. Because no class is active right now, we're just at teams/LinkedIn with no slash channel of any kind after that.

[00:04:13]
But if we click on either of these we should see I can alternate one and the other, and one and the other, and it works, right. And in fact, this is when the channel HPS is showing up. So it seems like once we have our full URL built with all of the pieces required, things are starting to look good.

[00:04:34]
>> Mike North: One last thing we want to do is make a request for that channel data. Channel data what might have some messages in there for us? So let's go to our channel route.
>> Mike North: Import fetch from fetch.
>> Mike North: We're gonna have model hook,
>> Mike North: That we're gonna make a fetch in there at some point.

[00:05:02]
I wanna check our little API examples thing to make sure that we're gonna hit the right URL, so let's check it out. Get a team which includes channels.
>> Mike North: So we can get a single team, we can get team channel messages. So I think we're just gonna do this in two steps, seems okay to me.

[00:05:32]
So this is the path we want to hit to get data about a channel. And we can really easily just bring that up here and experiment. There's our teams, the name of the team, channels the name of the channel and,
>> Mike North: Get a channel.
>> Mike North: And there's a little button popping up.

[00:06:02]
>> Mike North: Interesting, let me give it a quick little check.
>> Mike North: Sorry, I think we gotta do that now. LinkedIn, channels, recruiting.
>> Mike North: There we go. I just had to use a channel name and a theme name that are actually in our database. That's the only thing I had to tweak here.

[00:06:32]
And there we go. So we get our channel data and we'll deal with messages in a moment. But this looks good to me and we can bring that into our route and then call this step complete. Const to response = await fetch. And then back tix cuz we're gonna replace this with something and replace this with something.

[00:06:58]
Now, here things are getting a little bit interesting because we've found ourselves at a route where although we get the channel ID we do not get the team ID. And so we kinda need to get a clue from our parent, from the parent route, the team route. What were the parems that you were passed?

[00:07:22]
What were the arguments that you received in your model hook? And there are two ways we could do this. If you've used Ember before you're probably familiar with modelFor, right? modelFor would let us get whatever the model is for the team route. So this would get us that team object and it's the same rules as in route templates where this will get you whatever a promise resolves to write you.

[00:07:50]
You won't get the promised, you'll get the resolved value, so you've seen this before, the best practice here and I mean this seriously, only reach up. Only go from child route, to parent route, to grandparent. You want to do that because you can be assured that they've all recently loaded their data and their stuff is still valid.

[00:08:12]
If you reach to the side, like to your brother or sister route, that data could be really old. And that route could never have been called yet. It may never have had a model, right? We never hit that URL yet. So you can run the risk of getting nothing, getting stale data.

[00:08:33]
It's generally gonna not be a good time. So only reach up your ancestry to your parent and grandparent. A new thing that's been added recently is we don't have to call modelFor necessarily. We can call paremsFor. And that gives you, for the same route, for the team route, what did its model hook receive as arguments.

[00:09:00]
So here we'll be able to get team ID. And now we can plug this together, I expect a build error cuz I saved at a weird time. teamId and channelId, so that's our response, return resp.json. And that should give us the channel. And we'll just wire that up real quick.

[00:09:27]
And we can say, the title is now gonna be this.model,
>> Mike North: Title. We'll try name.
>> Mike North: I see I have an undefined in my URL down here. What did I do wrong?
>> Speaker 2: You need teams- [CROSSTALK]
>> Mike North: Thank you.
>> Mike North: Okay, perfect. That was it. That's all it took.

[00:09:57]
So now we've got recruiting, job hunting, right? That's icing on the cake. This model description. There we go. Now our headers are changing and our channels, our list of channels changed as we go between teams. When we pick a channel, we can see the header changes with the title and the description of the channel.

[00:10:23]
We can see that all of these API calls are going out, they’re fetching real data so we have now through basically swapping out hard coded array in our routing layer. We replaced them with promises that resolved to similar data, we didn’t have to touch too much of our app.

[00:10:41]
I mean, the only way we touched our templates in other ways was to start using this data, right. To start consuming it in a deeper and more involved way.
>> Mike North: Just checking the test before I recall it.
>> Mike North: What's going on? Our tests are hard coded for a channel name called general.

[00:11:05]
So team sidebar test and we can pass this a team,
>> Mike North: right, so team sidebar wants a team now. And we could say, this set my team name general description looks like, that's fine, let's see. We expected this and we got this.
>> Mike North: So there's the username,
>> Mike North: I think I made the wrong fix here, let me just back this up real quick.

[00:12:05]
>> Mike North: All right, so we got the side bar. We've got the user, channels, okay. So we have to worry about a channel called general and I was passing it a team called general, that was the problem. So we'll go back into that.
>> Mike North: And we don't need to worry about the team's name, we just need to have,

[00:12:31]
>> Mike North: Something like that.
>> Mike North: Title.
>> Mike North: Let me just look at my template so I don't go too much deeper into this. There's my model.name. So it should be name and description for the header but we're-
>> Speaker 3: [INAUDIBLE] array brackets.
>> Mike North: Pardon?
>> Speaker 3: Your channels.
>> Mike North: Thank you.

[00:13:03]
>> Mike North: And this should be name in fact and we're good to go. All right, so the further we parameterize these components, we have to go back and do little tweaks to our tests, because they're getting empty stuff at this point.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now