Jason: Alright, so let's set up our project
and also start to load some recipe data
from the Forkify API.
And here as always, I already have the starter files loaded.
Now this time we have a bit of a different structure here,
so I have index.html out here, but then all the rest,
all four assets for this project are here
in the source folder.
So in the source, we have images, JavaScript, and Sass.
So for JavaScript, right now we have controller.js,
which contains this little starter code here.
And then I have this Sass folder.
And in case you don't know,
Sass is basically a better way of writing CSS,
which has some nice additional features,
which makes writing CSS in a large scale application
a lot easier.
Now, browsers actually don't understand Sass
and so it has to be converted to CSS.
And so Parcel is going to do that for us.
And so I left these Sass files here
so that you can see that Parcel is actually also capable
of doing that.
And then here just some images and of course down here,
we have our flowcharts and also a small diagram
about the architecture.
Okay.
But now let's open up a new terminal here.
And then just like before we need to initialize
a new project by writing npm init.
And so this command will then create or package .json file.
So this project should be called simply Forkify
and the version might be version one.
Here, let's just say Recipe application,
or really whatever you want.
Then this one doesn't matter neither this one.
And now you can just add your own name here if you'd like.
And so that's it.
And so again,
this now created this package.json file right here.
Let's get rid of this one here actually,
or actually let's just change it to .html.
So this is kind of our entry point
so let's specify it here,
even though it's not really important.
And here I will start by setting up the npm scripts now.
So just as we did in the last section,
so this one is going to be npm start instead.
And here we will want to start Parcel on index.html.
So index.html is again going to be your entry point.
And then since we are here,
let's also already add or build script.
So basically the command that we are going to run
in the end once we're already building the application.
And again, index.htm.
Now, sometimes in projects we don't even have an html.
And so of course the entry point
can also be a JavaScript file.
And also this could be in a different folder
and we can specify all that here in the Parcel command.
But once again, we are just keeping it very simple here.
Now, in order to actually run Parcel,
of course we need to install it.
Now in the last section, we simply installed Parcel
by writing npm install Parcel,
and then as a dev dependency like this.
And so this would then basically install
simply the latest version that is available on npm
for Parcel.
And at the time I'm recording
that is version one point something
However, Parcel 2 is almost ready at this point.
And so I want to use a beta version of Parcel 2
so that you can use Parcel 2 in the future.
Alright.
So if Parcel 2 was already out,
then we would simply write @2 like this.
However, right now it's just a beta version.
And so I have to type @next
and then edit as a dev dependency.
So again, I am writing @next here
to install a beta version.
So let me run this and in case you get any error,
then please go ahead and simply install Parcel@2.
So you see here that this is going to install
at 2.0.0-beta.1.
Now okay, and here we go.
So again, you see that we are at 2.0.0-beta.1.
And if you got some error here again,
then please try a Parcel@2.
So it's really important for the rest of this section
that we are actually all on Parcel 2 dot something.
So here it doesn't matter if you have 2.1 or two or three,
but it should be two.
So that's what matters from this part.
And so now let's actually start Parcel
by running our npm script, npm run start.
And actually the start script is a special one in npm
for which one you don't even need the run.
So you can just write npm start
and that will then call your start script.
So it's installing Sass and now we got this error here
for the module, Sass.
And so lets quit this here with control C
and then I just say, npm install.
And so this will then install Sass here for us.
But if you're still running into some kind of error
with Sass here then please just try to install Sass
using the exact same version number.
So npm install Sass, and then at 1.26.10.
And so that should then fix any remaining problem.
And if it didn't, so if even after that
you still run into some problems either with Sass
or with installing Parcel or running Parcel,
then please take a look at the frequently asked questions
in the GitHub repo.
And only in the last case, you can of course also ask
in the course Q and A section.
But anyway, if we now try to run npm start again,
then it will work.
And indeed here it is.
So we now have to note modules folder,
which contains well tons of modules.
And then we also have our distribution folder, right?
And you see that here everything is in one folder.
So our index.html and then also the controller script,
which is this one, well not really this one,
but the compiled one.
And also you see that now we have an actual CSS file
and you also see all the images.
So a real CSS file, let's take a look at index as well.
And so you see that now it replaced the controller js
here in the source and also here I was referencing
the SCSS file, so the SCCS file.
And it is because of this that Parcel actually knows
that it needs to compile the Sass file to CSS.
So basically I referenced the Sass file here
and therefore Parcel knew that it had to include that file
in the distribution as well and to also replace
the under link to the actual final CSS file.
And the same is true for all the images.
So it basically copied all the images
to the distribution folder and gave them a new name
and replaced their source here in the html.
And this is very important to keep in mind
as we go building this project.
But of course this folder here
is not really important for us in development.
So everything that we will develop
will be here in the source folder
and only what we then see in the browser
is actually coming from this distribution.
So again, that's the whole logic of having a module bundler.
So it takes, or basically a raw source code
and compiles it into this nice package here, let's say,
so this folder that is ready to ship to browsers.
So for now we no longer need this html file
and so we can now think about our controller here
and actually think about making our first API call.
And we can actually also open the page here
by clicking option down here.
Well, that opened in another tab for me.
So let me just copy it right here.
Let's open up the developer tools as well,
but for now of course we have nothing here
because we don't have any code yet.
But let's just lock something to the console,
just to see that our Parcel setup is working.
And you see that it already built a new version.
And indeed we have tests now in our console.
Great.
So everything is working and so yeah,
let's now make our first API call.
Now, for this project I actually developed my own API
so that we are not dependent on any third party services.
And the API is at this page.
So let's copy it and let's go there
to check out the documentation.
So any good API needs some sort of documentation.
And so this is the documentation that I wrote
for our Forkify API version two.
So version one was for the old version of this course.
So some details about this API
is that search terms are limited.
All you can search for is the terms
that are in this list here,
but to test this application that should be enough.
And you can only make 100 API requests per hour
in order not to overload our servers.
Because again, this is here my own API
that I'm running on my own server.
Then the API key is what we will need
to upload our own recipes.
But again, more about that later.
And then here we have basically our main URLs
or routes of this API.
So the first one is used to get all the recipes
or to create a recipe.
But for now let's focus on this one,
which is simple to get one single recipe.
So the path of this part of the API is this here.
So this URL then slash recipes slash the ID of a recipe.
And down here is an example of that.
So for example, this one here might be the ID
and then here the key,
but again the key doesn't matter for now.
And we can click on this and then see exactly
the kind of result that we will get.
And so actually this is the URL
that for now we will use in our code
to basically get exactly this recipe here
in our application.
So let's copy this and go back to our code.
And so now as always to make an Ajax request to an API
we use the fetch function.
And now that we have this,
let's actually create some function around this.
So an async function so that we can use a single wait.
So let's call it showrecipe.
So an async function.
And then here as always, we use a try catch.
And if there is an error, we want to alert that error.
So very simple error handling for now.
And now let's take this here and await it
and store the result into the res variable,
which stands for response.
And I hope that all of this here
is nothing new for you at this point
after the last couple of sections.
So just keep in mind that using the fetch function here
will return a promise.
And so, since we are in an async function,
we can then await that promise.
So basically we will stop the code execution here
at this point, but that's not a problem
because this is an async function anyway,
which only runs in the background.
So we are not blocking our main thread of execution here.
But anyway, once we have that result,
we then need to convert that to json.
So as always, let's create a data variable
and then await the response .json.
So the json method is, again, a method that is available
on all the response objects.
And a response object is exactly
what the fetch function here returns.
And so yeah, we can then call json on that response,
which returns another promise,
which we then have to await again.
And in the end we will then get our data
stored to that variable.
And then that's actually console.log,
both the response and also the data.
So, give it a safe.
And we also should call this here right at the beginning
because otherwise nothing is going to happen.
And so which one is ours? Here we are.
And you see that we already have a result here.
So first is the response.
And so again as I mentioned,
this returns a response object,
but then the data itself is here.
And so we get this status here and then the data itself.
Make it a bit bigger here.
And so then here, inside of data we get the recipe itself.
So it contains all of this data here, cooking time,
the ID itself, then the ingredients, publisher, servings
and so on and so forth.
So that works beautifully.
And as always, we started here assuming
that there will be success,
but now let's try to create a wrong ID here,
which doesn't exist on the server.
So just something like this and let's see what happens then.
And so you see, we get the bad request.
Here then in the response,
we can see that ok is set to false.
And so this is what we're going to use, remember that.
So when ok is set to false
means that there was some kind of error in the fetch.
And so we can then use that to create our own errors.
So again,
just like we learned in the asynchronous JavaScript section.
But then we still get a response here
and this response says fail.
And then also this message of invalid_id
and then the ID that we provided.
So also the API itself returns a nice error message.
And so lets actually use that error message now.
Because simply bad requests
is not a very informative error message.
It's way better to actually use the one
that the API returned to us.
And so that's at .message of this object.
So, we need to do that after this one here.
And so we can say if res.ok is false.
So basically if response is not okay,
then we want to throw a new error.
And then in there we can use the .message property
that I just mentioned.
And again, that one is already coming from the data.
So from the response of the server
while the ok property is stored in the response itself.
And then that's also provide the status code.
So that is at res.status.
Now okay and so...
And you see that somehow we already get the error here,
even though we're not at Chrome.
But anyway, that alert window appeared,
of course because down here the catch error,
we are alerting exactly that error
that we throw here in the try block.
Right?
And so as we go here, let's just try to reload.
And so indeed, here we get our error as an alert window.
But now let's take it back actually...
But now let's take it back actually.
And so when we're back then our data here is also back here.
Now just to finish, lets actually format that data
a little bit nicer.
So basically I want to create a new object
based on this object which has some better variable names.
So here we have for example these underscores
and these are very unusual in JavaScript.
And so many times what we do
is to basically kind of reformat this object
that we get here.
So basically I want to get rid of these underscores.
And so...
So lets create a new recipe variable,
which should be data.
And then remember that it is again data,
and then dot recipe.
So let's see that again, just to make sure.
So this here is the data variable.
And then in there we have data again
and then in there is .recipe.
And so here we have recipes on both sides
and so we can use this structuring.
So let's take that back.
And I called this one a recipe with let
so that we can now basically create a new recipe object
based on that.
So the id is the recipe.id.
Your title is gonna be recipe.title.
The publisher will be recipe.publisher.
And there would have been other ways of doing this,
but this is kind of the quick and dirty way (chuckles).
So source URL is going to be recipe.source_url.
So this is one of the ones I wanted to change.
Then there's also an image URL property.
And this one I want to simply call image,
image_url.
Then the servings might be just recipe.servings.
And we're almost done here.
So cooking time is the recipe.cooking_time
with an underscore.
And finally ingredients is recipe.ingredients.
Now let's actually get rid of this
and simply lock to the console, the recipe object
that we just created.
And here ingredients looks wrong ingredients like this
and here the same.
Everything else looks correct.
And yeah.
So here is our nicely formatted recipe
that we just got from the server.
And of course, that would work for other recipes as well.
So let's go back to our documentation page
and get some other ID.
And so that ID, we can basically get from the search URL.
So this path here will take us
to all the recipes there are for a certain search query.
So let's try this one here, which is for pizza.
So you see it is the route.
So the URL that I just told you slash recipes.
And then we have this query, search set to pizza.
So after this question mark.
And this is a very common format
of basically sending variables over your URLs.
So search is like a variable and then pizza is that value.
And so in this case, this is the query string.
And in this case, what we want to search for is pizza.
And so let's now just take any random ID of this.
So with just copying it, let's go back here
and then I will just duplicate this line
and comment it and then replace this part here of the URL
with this other ID.
So you see it's slightly different.
And so now we should get a different recipe.
So let's see.
And yeah, this time it is called Pepperoni Pizza Burgers.
And so of course later in the real world,
we will then get these different IDs
from our search results here in the sidebar.
So, we successfully started up our project
and already did our first API call to the Forkify API
that I created just for this project.
So this was a nice start of the project.
And now in the next video,
we will then actually already render this data
to the user interface
in order to create something like this here.
And I hope you're excited for that.
And so let's quickly move on.