Check out a free preview of the full Rapid Development on AWS: React, Node.js & GraphQL course:
The "Creating an S3 Image Component" Lesson is part of the full, Rapid Development on AWS: React, Node.js & GraphQL course featured in this preview video. Here's what you'd learn in this lesson:

Since image URLs must be fetched asynchronously, Steve rebuilds a component found in AWS Amplify library to asynchronously loading images found on S3.

Get Unlimited Access Now

Transcript from the "Creating an S3 Image Component" Lesson

>> Steve Kinney: Okay. So, this leads us to our next problem is I spent a good amount of time telling you that this isn't a great pattern. And you're like part of you like I can see a bunch of you squinting and looking at it, which is a sign that there's a code smell.

[00:00:13] Right? If you have to squint to, okay so, this is happening and then that, It's not great. It's worse when you consider that every single component that had to use one of these images you would have to do that in. Right, that's not great. So when that happens, usually the best way to solve problematic code like that is to create an abstraction.

[00:00:37] And abstraction is a fancy computer science way to say, sweep the sadness under the rug, right. And so, let's give ourselves a component that doesn't make us sad. We'll just use that when everywhere, and then we won't see the terrible things we did. Cuz sometimes you have to write squirrely code, right?

[00:00:53] Like under the hood, all computer are is electrons going through a copper wire, right? There's some squirrelyness somewhere, eventually we just put up enough layers of abstraction where this is a level of stuff that'll make our stomach turn. Right, this is not assembly as weird as it is.

[00:01:08] So what we're gonna do is make a component that will take a key. It will render nothing until it's figured out what the URL is, and then it will render the image. Okay? Everyone's like sure, anything is better than this. Cool. So what we'll do is we could make a whole new file for this component, I'm not going to.

[00:01:32] I'm just going to say class, we'll call this one S3Image, which is suspiciously close to what AWS Amplify React calls theirs.
>> Steve Kinney: And there will be a component And we'll start out just by doing.
>> Steve Kinney: We can pass in a file, which is, right now we're just moving the problem around.

[00:02:03] It's not actually gonna solve anything yet. But let's get it in place. I'm gonna wrap all of these into an article, not for a really great reason, but mostly because it helps with my CSS. Because it lets me effectively control the size of these, cuz if I upload a giant image it's gonna take up my whole screen, so this is just a quick little move.

>> Steve Kinney: Okay, so let's go ahead and use this component.
>> Steve Kinney: Here we'll actual say. We'll actually call this one s3image m-i, m-a.
>> Steve Kinney: And we'll just take a look at it real fast. You'll just basically see the same image with a purple border.
>> Steve Kinney: Or not.
>> Steve Kinney: I called it file.

>> Steve Kinney: Cool, you have a second, same basic idea, just bound in a little, other element right now. So, what we're gonna do is we're gonna set this up. So that it'll show nothing. But I wanna say, hey, I wanted this component, I'll give you a key. It will then go ahead and fetch the actual image itself, right?

[00:03:36] So we can take this away, all right? And this is one of the things that we have to deal with because of some of the really cool benefits we get from storage. It's just this hoop that you have to go through. If you have the key, I wanna see if you can even get this image, cuz otherwise, we have an URL, turns out it's like your tax return.

[00:03:51] Right? This will actually allow us to keep that identity control in place. Cool. And so, here's what we'll do, we'll say in this S3Image we'll say there will be a source and right now we could have any kind of asset in here. I'm just assuming they're all images which is not great.

[00:04:12] We'll say it has a source that's null. And instead of a file, this is gonna actually just take a key in this case. And if
>> Steve Kinney: this.state.src. If it doesn't exist or if it equals null, which is faulty. We'll return null.
>> Steve Kinney: So if that doesn't show up at all we just won't show the component until we actually have the image ready.

>> Steve Kinney: Let's just shorten that up a little bit. We're gonna use it again. Otherwise,
>> Steve Kinney: show it with the source. Now we need a way to take the key and turn it to the source, we've already seen that before. Well imagine key unfortunately in React it means something, it's like when you have a collection of things it's which one is it so the virtual dome can do all of its fancy diffng, so we'll call ours S3 key.

[00:05:18] So what we'll do is when this component mounts.
>> Steve Kinney: Right, we'll say const. We haven't implemented this yet. s3key port from the props
>> Steve Kinney: Go head and then go fetch and when you have it
>> Steve Kinney: So now we have a component that basically takes an s3key. Automatically goes ahead and can figure out how to fetch it and updates itself.

[00:05:59] So you can use these now. You'll see nothing on the page until it's loaded. Once it's loaded, then you'll actually see it on the page. All that squirrelly code we wrote before? We've basically put it in a little box, sealed that box shut, and no longer have to look at it anymore.

[00:06:15] All right, so then we can change a few things here which is.
>> Steve Kinney: Just get the keys back. I'm avoiding the word keys because it's slightly problematic in React.
>> Steve Kinney: And so we'll say file, and we'll say this is now s3key. And ideally we should have the same code.

[00:06:41] We just took all that really squirrely stuff with the promise.all array we're asynchronously fetching. Cuz the thing about promise.all is that if a single promise in that array fails the entire array fails, which is not great. All right, cool. Finding that file did not work. So let's see

>> Steve Kinney: See what it was. The source is now, the source is this entire URL. Woo. That's a gnarly URL?
>> [SOUND]
>> Steve Kinney: All right, we'll see what we got here.
>> Steve Kinney: Sample image, should be file.key.
>> Steve Kinney: All right, there we are. This is the entire object with the key as well as the E-tag as well as the date last modified and the size.

[00:08:30] I just needed the key in this case. So now we have a way to show images and it will handle all of the asynchronous loading. That was really all that we attempted to do there was abstract that away. The other thing that would be nice to do is, have the ability to add one as well.

[00:08:48] So, what do we think that looks like? We've got a name which is useful for setting a key and we've got the entire file. We saw, if we go back to this slide from earlier,
>> Steve Kinney: That's good. Hold on real quick. All right. Which one of these do we believe will, I'm not gonna use the other word, place an object into an S3 bucket?

>> Steve Kinney: Put, cool. So what we'll do is we'll replace this with
>> Steve Kinney: Storage.put, maybe we spell it right.
>> Steve Kinney: All right so it takes a key, which we've seen previously was the file name. And it takes some kind of object, so we'll take the entire file.
>> Steve Kinney: Cool, and then when that succeeds, we'll get a promise.

[00:09:52] And so what we'll do is, we'll take that and we'll add it just to the entire list of things. So well put it in there with the name of the file and then we'll get some kind of response back from s3. We'll say console log, we'll say so we know exactly what happens storage.put with the response

>> Steve Kinney: And this.setState.
>> Steve Kinney: This.state.files, and just add in the response as well.
>> Steve Kinney: So now we're gonna play a fun game called pick a random image from Steve's computer.
>> Steve Kinney: Will it be an Arduino board, or will it be a meme? Looks like it's gonna be an Arduino board.

>> Steve Kinney: This is gonna be LED. And then I'll hit Submit.
>> Steve Kinney: Cool, I need a unique key prop.
>> Steve Kinney: That's interesting, so let's look at the response first, and I'll figure out what happened. So we can see that we got this brand new key in this case that we can use.

[00:11:15] But then, this got very angry at me for a second so we'll take a look at that shortly. Should have a key prop, that should be the case.
>> Steve Kinney: I gotta spread that array out.
>> Steve Kinney: Cool, all right you can see both images are in there now.