1 00:00:02,340 --> 00:00:07,350 So now I also want to display a little map preview here and there are different ways of doing that of 2 00:00:07,350 --> 00:00:11,000 course and later we'll also add an interactive map to this app. 3 00:00:11,010 --> 00:00:12,970 For now, I just want to have a static image, 4 00:00:12,960 --> 00:00:19,570 so like a map snapshot and the cool thing is Google has an API for us which generates such snapshots. 5 00:00:19,620 --> 00:00:24,810 You can google for Google Maps static API to find the official documentation where you can learn all 6 00:00:24,810 --> 00:00:26,010 about that of course 7 00:00:26,190 --> 00:00:29,340 and in the end, using that API is super straightforward. 8 00:00:29,400 --> 00:00:35,820 You just need to send the request to this URL and this already gives you back an image, so you 9 00:00:35,820 --> 00:00:40,650 can just use this link on an image component and you're good. 10 00:00:40,650 --> 00:00:46,740 The only tricky thing here is this API key thing, there you need your API credentials and for that, you 11 00:00:46,740 --> 00:00:49,300 need an API key. 12 00:00:49,410 --> 00:00:55,590 Now for this, you can just click on your API key here and generate one and now you can select a project 13 00:00:55,590 --> 00:00:59,660 which you already have or you create a new project and for that 14 00:00:59,670 --> 00:01:05,220 you need to cancel here and instead scroll down a bit further to this 15 00:01:05,250 --> 00:01:10,110 getting started, activate the API part here and click on get started here. 16 00:01:10,110 --> 00:01:15,840 Now once you do that, you're taken to the Google Maps platform console where you can now enable the 17 00:01:15,840 --> 00:01:21,930 different Google Maps features you want to use and here, I'm interested in maps which will later help 18 00:01:21,930 --> 00:01:29,590 us use this interactive dynamic app on Android and I'm interested in places. 19 00:01:29,670 --> 00:01:31,420 So these two things should be checked, 20 00:01:31,470 --> 00:01:36,430 we don't need the routes because we're not building any navigation features here and with that, we can click 21 00:01:36,430 --> 00:01:40,600 on continue, select a project and now either select an existing project or simply create a new 22 00:01:40,600 --> 00:01:45,820 one and I'll create a new one here and name it React Complete Guide but you can name it whatever you 23 00:01:45,820 --> 00:01:47,560 want, click next here 24 00:01:50,460 --> 00:01:53,370 and wait for this to be generated. 25 00:01:53,370 --> 00:01:57,320 This should be relatively fast and now we're worried about pricing whilst 26 00:01:57,360 --> 00:01:58,680 this is loading. 27 00:01:58,770 --> 00:02:02,970 You can generally use this for free but you need a billing account and 28 00:02:02,970 --> 00:02:04,740 that's what I'm getting asked for here. 29 00:02:04,770 --> 00:02:06,080 You need a Google account of course 30 00:02:06,150 --> 00:02:09,930 and on this Google account, you need to have a credit card in order to use it, 31 00:02:09,930 --> 00:02:13,570 otherwise you can't use that unfortunately, it is what it is. 32 00:02:13,590 --> 00:02:15,180 So you need a credit card, 33 00:02:15,180 --> 00:02:19,590 you need to have a billing account set up in your Google account and then you can use this logged in 34 00:02:19,590 --> 00:02:26,100 google account for this project which is what I'm doing here. With that enabled, 35 00:02:26,160 --> 00:02:28,550 you still will be able to use that for free, 36 00:02:28,550 --> 00:02:33,570 you got a very generous free tier and attached you find a link to the pricing of the Google Maps platform 37 00:02:33,810 --> 00:02:39,540 and only if you breach certain limits which we'll not breach for the little usage which we have here in 38 00:02:39,540 --> 00:02:43,200 these videos, only if you would breach these limits you would pay. 39 00:02:43,200 --> 00:02:47,520 Now still be aware that there can be a point where you need to pay and that it depends on how 40 00:02:47,520 --> 00:02:52,340 much you use the API and therefore definitely check out the pricing docs. 41 00:02:52,380 --> 00:02:57,190 Now here, I got this all enabled now and I'm just finishing this up 42 00:02:57,300 --> 00:03:03,160 and by the end, you should be presented with an API key which of course I'll invalidate after these recordings. 43 00:03:03,180 --> 00:03:06,440 So you can't use mine but you should take yours instead and 44 00:03:06,460 --> 00:03:11,610 now this is the API key which you need to insert here into this URL. 45 00:03:11,670 --> 00:03:18,150 So now I'll just copy this entire URL here and move that over into our code and there, 46 00:03:18,210 --> 00:03:23,790 I now want to output an image here which points at that URL because as I mentioned, this is how 47 00:03:23,790 --> 00:03:27,900 you can get this image, this URL returns an image. 48 00:03:27,900 --> 00:03:33,390 Now what I'll do therefore is I'll create a new component here which I'll name MapPreview.js because 49 00:03:33,390 --> 00:03:39,090 I'll also use it in another place of the app later where I import React from React and where I then import 50 00:03:39,180 --> 00:03:44,890 image and stylesheet from React Native, like this. 51 00:03:47,620 --> 00:03:55,180 Then here, I'll create my map preview component which receives props of course unsurprisingly, which needs 52 00:03:55,180 --> 00:04:02,310 to return some jsx later and set up some styles here with Stylesheet.create 53 00:04:04,970 --> 00:04:11,600 and of course also export this map preview component. 54 00:04:12,050 --> 00:04:16,430 Now in here, I want to generate this URL which I just talked about, so here the 55 00:04:17,660 --> 00:04:26,870 image preview URL should be generated and that can be done by using back ticks here so that I can 56 00:04:26,900 --> 00:04:32,540 add dynamic content into the text easily and then copy in that URL you just copied from the 57 00:04:32,540 --> 00:04:34,110 documentation here, 58 00:04:34,190 --> 00:04:37,790 make sure it's all in one line because by default it's not, 59 00:04:37,790 --> 00:04:40,360 so make sure it's all in one line 60 00:04:40,370 --> 00:04:42,460 otherwise this won't work 61 00:04:42,460 --> 00:04:44,590 and now of course there are a couple of segments you need to replace, 62 00:04:44,600 --> 00:04:50,210 for example here, the center equals part. By default, this points at the Brooklyn Bridge and you can enter 63 00:04:50,270 --> 00:04:55,100 addresses here but you can also enter latitude and longitude pairs here. 64 00:04:55,100 --> 00:05:01,820 So what I'll do here is I'll dynamically add two pieces of information here separated by a comma and 65 00:05:01,820 --> 00:05:04,090 the first thing is the latitude. Here 66 00:05:04,100 --> 00:05:06,680 I expect to get this on my props, 67 00:05:06,680 --> 00:05:12,100 I expect to get a location prop and of course this can be any prop name of your choice which then should 68 00:05:12,110 --> 00:05:20,600 have a lat key and here, I want to have a long key, an lng key as well, so that will be the latitude and longitude 69 00:05:20,660 --> 00:05:21,610 of the location 70 00:05:21,620 --> 00:05:27,130 I want to preview. Now the zoom factor, I'll set this to 14, 71 00:05:27,200 --> 00:05:33,110 you can experiment with different factors, this influences basically how far the map is zoomed in or out. 72 00:05:33,170 --> 00:05:36,350 You can also play around with your size here. 73 00:05:36,360 --> 00:05:42,230 Now since I will have a map preview container that I'll typically use with a height of 200, I'll 74 00:05:42,230 --> 00:05:48,520 set the height to 200 here and I will set the width therefore to 400 here. 75 00:05:48,740 --> 00:05:55,640 Of course, you can use a bigger size here than you'll use for the container to display the image later, 76 00:05:55,640 --> 00:06:01,610 just be aware that if you are fetching a super large image here, it will of course be too large, 77 00:06:01,610 --> 00:06:06,290 too much data to download, it will load slower and you might not need that. 78 00:06:06,350 --> 00:06:12,260 So you should aim for a size of the map image here which kind of fits the container where you want to 79 00:06:12,260 --> 00:06:18,740 display it, doesn't have to be the exact same size but roughly. Now map type is how the map should be displayed, 80 00:06:18,740 --> 00:06:23,990 you could use satellite here but I'll stick to the standard road map and now you can also add markers 81 00:06:23,990 --> 00:06:24,870 to that map. 82 00:06:24,950 --> 00:06:27,840 Now there are a couple of markers set up in this dummy snippet, 83 00:06:28,040 --> 00:06:34,700 I'll get rid of all of them but one so that I just have markers here, 84 00:06:34,700 --> 00:06:35,600 color red, 85 00:06:35,630 --> 00:06:37,220 a label of a, 86 00:06:37,220 --> 00:06:42,890 this can be a single character here like ABC and then the latitude and longitude where this marker should 87 00:06:42,890 --> 00:06:46,440 be placed and of course, that's again props.location.lat 88 00:06:46,490 --> 00:06:53,960 and then here a comma and thereafter, replace this number with props.location.lng. 89 00:06:54,470 --> 00:07:01,500 Placing such a marker is optional but of course, I want to show the user where this is. 90 00:07:01,740 --> 00:07:09,360 Now I need the API key, so I'll copy this key which was generated here and replace this here. 91 00:07:09,480 --> 00:07:14,610 Now I can't paste it in like this but actually, I want to manage this in a separate file because I will 92 00:07:14,610 --> 00:07:18,490 use that API key in other places of the app as well. 93 00:07:18,570 --> 00:07:24,180 So here, I'll create a new file which I'll name env.js for environment to set up some environment variables 94 00:07:24,870 --> 00:07:34,970 and there I'll set up an object with my Google API key and that should be this value here and then 95 00:07:34,970 --> 00:07:44,820 I can export this and of course therefore, that should have a name, vars equals and then I export vars 96 00:07:44,820 --> 00:07:45,980 here. 97 00:07:46,050 --> 00:07:51,000 So with that, I can simply import from that env file and that's just what I'll do here, 98 00:07:51,000 --> 00:08:02,300 import env from the env file here and that just stands for environment variables as I said and now dynamically 99 00:08:02,300 --> 00:08:03,110 inject this here. 100 00:08:03,110 --> 00:08:07,670 So now we have one place where we can change that key and where we can also then import it from in all 101 00:08:07,670 --> 00:08:09,550 the different places of our app. 102 00:08:09,590 --> 00:08:14,900 So here I'll dynamically inject env.googleapikey. 103 00:08:15,010 --> 00:08:17,900 So with that, I got the image preview URL set up, 104 00:08:18,100 --> 00:08:23,550 now in this component, we of course need to return the image preview and that generally is that 105 00:08:23,560 --> 00:08:30,250 view I have here in the location picker. So I'll grab it from there and add it in the map preview, like this, 106 00:08:31,500 --> 00:08:35,130 though the fallback content in there, 107 00:08:35,130 --> 00:08:41,790 I actually want to pass that in from outside, so I'll cut this out again and move that back into the location 108 00:08:41,790 --> 00:08:42,420 picker. 109 00:08:42,420 --> 00:08:44,370 However not like this but instead here, 110 00:08:45,180 --> 00:08:53,440 import this newly added map preview component, so import that from ./MapPreview, 111 00:08:53,480 --> 00:08:55,910 so this new component we're currently working on, 112 00:08:56,030 --> 00:08:57,960 add this here, 113 00:08:58,220 --> 00:09:05,240 map preview and then have this check for this fetching and the indicator and the fallback text in here. 114 00:09:05,270 --> 00:09:12,250 So in map preview, I will therefore only have props children in here to output what's added between the 115 00:09:12,250 --> 00:09:15,480 opening and closing tag but that's just fallback content, of course 116 00:09:15,480 --> 00:09:21,760 I do care about outputting the real preview here. Now for that we have to make sure that image preview URL 117 00:09:21,820 --> 00:09:28,190 actually also can be empty in case no place has been chosen yet, so I'll create a variable image preview URL 118 00:09:28,220 --> 00:09:30,610 and just assign a value here 119 00:09:30,610 --> 00:09:37,990 and I do want to assign a value if props.location is set because that also cannot be set in case 120 00:09:37,990 --> 00:09:44,980 we haven't picked a location yet and now image preview URL is either empty or it's this URL depending 121 00:09:44,980 --> 00:09:51,400 on whether we have a location passed in on the location prop and we can now use this down there to output 122 00:09:51,400 --> 00:09:52,220 something 123 00:09:52,220 --> 00:09:56,020 and by the way since I'm using view here, of course we should also make sure we import 124 00:09:56,020 --> 00:09:57,640 view. 125 00:09:57,870 --> 00:09:59,290 Now how do I use this URL? 126 00:09:59,310 --> 00:10:02,160 Well if we do have it, I want to use it to output an image, 127 00:10:02,160 --> 00:10:06,170 otherwise I'll show this props children fallback content. 128 00:10:06,240 --> 00:10:08,580 So here we can check for 129 00:10:08,580 --> 00:10:10,140 props.location, if that's set 130 00:10:10,140 --> 00:10:12,230 I know I'll have an image URL as well, 131 00:10:12,240 --> 00:10:18,600 we could of course also just check the image URL existence and if this is set, I'll output an image 132 00:10:18,600 --> 00:10:19,260 here, 133 00:10:19,260 --> 00:10:25,200 if it's not set, I'll output props children like this, so I'll output my fallback content. 134 00:10:26,110 --> 00:10:29,960 Now the image here will receive some styling, a map 135 00:10:30,040 --> 00:10:39,650 image and a source and the source here takes a URI which points at image preview URL because 136 00:10:39,650 --> 00:10:42,010 that will be a network URL, a network image, right? 137 00:10:43,000 --> 00:10:46,330 So now let's just bring over the styles from the location picker, 138 00:10:46,390 --> 00:10:54,520 I can take a map preview but I only want to bring over the justify content part and actually pass in 139 00:10:54,520 --> 00:11:01,390 the rest manually here and merge it, so I'll still pass in styles.MapPreview from inside my location 140 00:11:01,390 --> 00:11:07,300 picker and in the map preview, I now want to merge this with my styles I'm setting up here. So here I'll 141 00:11:07,300 --> 00:11:13,270 actually wrap this into an object where I pull out all the styles set up in map preview in here and 142 00:11:13,270 --> 00:11:19,240 merge in all styles set up on this style prop so that we can set styles from outside as well and merge 143 00:11:19,240 --> 00:11:26,980 them with our internal styles and now for the internal styles on the map preview, as I just said, I'll have justify 144 00:11:26,980 --> 00:11:29,050 content and align items in here 145 00:11:29,200 --> 00:11:30,850 and for the image itself, 146 00:11:30,910 --> 00:11:37,020 so for the map image, there I want to set this to take all the available width and height it can get 147 00:11:37,040 --> 00:11:41,410 and we need to set this because it's a network image. As you learned, for those you need to set the width 148 00:11:41,410 --> 00:11:43,040 and height of the image component. 149 00:11:44,710 --> 00:11:51,040 Now with that, we have the map preview component which either displays this map image or our fallback 150 00:11:51,040 --> 00:11:53,690 content which is passed in from outside 151 00:11:53,920 --> 00:11:57,640 and it does so by checking the location prop. 152 00:11:57,640 --> 00:12:02,950 So in the place where we use the map preview component which of course is the location picker, we need 153 00:12:02,950 --> 00:12:07,330 to pass in this location prop and the location prop, 154 00:12:07,330 --> 00:12:15,190 if we check the map preview, in the end has to be an object with a latitude and longitude or a lat and lng 155 00:12:15,190 --> 00:12:19,840 key. So therefore back in location picker, 156 00:12:19,910 --> 00:12:25,610 I want to pass in such a prop here and indeed, that's exactly what we manage here with the pick location 157 00:12:25,610 --> 00:12:32,870 which is of course no coincidence. That is an object with latitude and longitude or it's undefined initially 158 00:12:33,050 --> 00:12:36,300 and we do handle this case in the map preview component as well, 159 00:12:36,410 --> 00:12:41,060 if it's undefined, we just show the fallback content which is passed in from outside. 160 00:12:41,060 --> 00:12:46,880 So to location, we can just pass in the picked location and with that, we should now have a setup where we 161 00:12:46,880 --> 00:12:50,150 actually are able to see a preview of the place. 162 00:12:50,630 --> 00:12:52,490 So now here, we see the fallback content 163 00:12:52,520 --> 00:12:59,120 but if I now click on get user location, we see the spinner and then we see a real snapshot of the place 164 00:12:59,150 --> 00:13:00,010 we picked. 165 00:13:00,080 --> 00:13:02,180 As I mentioned, this is not where I am sitting right now, 166 00:13:02,180 --> 00:13:05,930 this is just some dummy place the emulator gives us. The same on Android, 167 00:13:05,930 --> 00:13:08,370 if I take a location here, 168 00:13:08,370 --> 00:13:12,140 now this is actually the Google headquarters which I selected by default there. 169 00:13:12,880 --> 00:13:17,370 So this works, now as a next step, 170 00:13:17,410 --> 00:13:22,570 I want to make sure that we can also pick this place on a map instead of just locating us.