Category Archives: javascript

DNY client (5 – Menu and filtering authenticated content)

dny-client-5 source code
src/core/Menu.js

We first look at how we decide whether a link is active or not. We do so by looking at the history’s path name and the current path. If they match, then we’re on that page and we color it orange.

The way how we get history is to import withRouter from ‘react-router-dom’ and then using it as middleware on our Menu component.

The history object is returned to our component as an object. Within this object, we look at property location, and find the pathname of what page we’re on.

Then we implement signout functionality for when we click on sign out link.
1) We first clear out jwt from the local storage
2) we then make a request to the server for it to signout the current user.

Finally, we implment the filtering of which menu item should be visible depending on whether we’re authenticated or not.

Basically, if our local storage has jwt property, then we’re signed in. We need to get this string, parse it into an JS object, and return it. Else, if this jwt property is empty, then we’re not signed in.

We then copy and paste template html into our code. Then use the previous functionality for
1) signing out
2) filtering menu items
3) coloring the active link

DNY client (4 – Signing in)

We first create a sign in page routing in our MainRouter. It routes to component Signin

src/MainRouter.js

We then create component Signin. It has email and password for the user to sign in with. The error is required for erroneous situations and the redirect to a specific referer page.

src/user/Signin.js

We have an authenticate function that gets the jwt token and stores it into local storage. We store the token value on key ‘jwt’.

But before we do so, we need to make sure the window object exists.
Once the token is set, we set the referer to yes.

Once the user clicks submit, we sign by passing in the email and password. We stringify that data and put it in the body of our POST request to http://localhost:8080/signin.

When successful, we should then get the response with token and some data. We then put this token into the localstorage and set the our redirect to yes so that we redirect to the homepage.

Before you sign in, clear your localStorage first by opening up Inspect Element, then click on the Application tab. On the left-hand side, you’ll see a clearStorage. Click on it to clear any key/values stores previously.

Now, on the left-hand side, make sure you’re still on the Application tab click on the localhost URL. On your browser navigate to localhost:3000/signin. Then sign in using correct credentials. You’ll see that the key/value will be updated with the token given by the server. This is so that whenever you make future requests, you’ll be using this token with each request. The server will verify it and thus authenticate your requests.

After the successful sign in, you’ll be redirected to the home page.

DNY client (3 – Creating a User)

On the client side, make sure we create the event handler for the submit button:

src/user/Signup.js

On the server side, make sure use cors.

To set up: npm i -S cors

app.js:

Now when you fill in the username, password, email, (like I did in the screenshot) you’ll see that the password is ‘compaq’ and does not have a number. Thus, you’ll get a bad request:

Click on the Network tab to see what this bad request is about. You’ll see the request, which is called signup. Click on signup.

In the response from the server, we see that the text tells us that we need a number in our password:

So change our password so that it has a number. This time, when you submit, you’ll see that the response to our request will be successful. When you analyze the response to our request, you’ll see that the json response will have a success message:

Go into your mLab account and you’ll see that our users have the information we just used to create a user:

Now, if you try to submit the same data for registration, the response from the server will tell you that the email you’re using to register already exists:

DNY client (2- Routing)

download dny-client-2
install react router dom package: npm i react-router-dom

In App.js, we extract BrowserRouter from react-router-dom which is the package we just installed.
BrowserRouter needs Router components to let it know where and how to route. Thus we need to implement MainRouter. MainRouter routes ‘/’ to a component called Home. We need to implement this Home component also.

src/App.js

Implement MainRouter

This is the main routing mechanism. We basically extract Route and Switch from the package we just installed. In our case, we need a simple router to route path ‘/’ to component Home

We create this pure component so that it can be used inside component BrowserRouter in App.js
It routes different paths to different components.

src/MainRouter.js

Implement Home component for viewing

We created a router that routes to a Home component. Let us implement that Home component.

First, we create a core folder in src. Then we put Home component in there, which basically just displays the data. This simple display of data is fitting to use a pure component like so:

src/core/Home.js

Hence, this core folder will contain all display of views using pure components.

Adding Sign up Page

Create another folder called user, we’ll put all user-related UI in there. Then create file Signup.js:

src/user/Signup.js

update src/MainRouter.js like so:

DNY Client (1 – setup)

create-react-app dny-client

cd dny-client

npm start

You’ll see the default site.

Open your project with Code and remove these files:

  • App.test.js
  • ServiceWorker.js
  • setupTests.js
  • logo.svg

Edit these files to like so:

App.js

index.js

Go to Bootstrap Material.
We want to put the CSS into our index.html

copy and paste the link int the index.html

Add className container to your App and return the site.
You’ll be able to see some CSS take effect.

App.js

React Router DOM

npm i react-router-dom

DNY Node API (4 – sign in using JWT )

npm i jsonwebtoken

npm i cookie-parser

dnyNodeAPI-authentication

Creating a User

After creating a user correctly, we get a message saying that a user has been created.

Ensuring user creation correctness

In validator/index.js, we have function userSignupValidator function that ensures we check for the format of the data for when user is created.

We use this function as a middleware in
routes/auth.js

This means that userSignupValidator is used to validate the incoming JSON’s properties. Only when it passes do we continue on to signup function.

validator/index.js

Be sure that you include a number inside your password:

Make sure you include a name when you register for an account:

For your email, ensure to have it in an email format:

Successful Signin

In order to sign in, use /signin, then click on tab Body, choose raw and then JSON format.
Type in a JSON object with key/value “email” and “password”. Then click send. If your credentials are correct, you’ll get an object back with a token key/value.

Copy and paste the value into Headers. In Headers, create a key called “Authorization”.
In the value, type “Bearer ” with a space at the end. Then copy the token behind it.

You are not set up to create/update/delete posts, get/update/delete your own user data.

DNY node api (1 – setup)

  • download source
  • unzip the source code
  • go into directory and type npm install to install the modules
  • Once the packages are installed, run it npm run dev
  • Go to localhost:8080, then check terminal for logs

Set up

Open terminal, navigate to ‘Desktop’

mkdir dnyNodeAPI

cd dnyNodeAPI

npm init

press enter for all selections

npm install express

Then check your node_modules folder and you’ll see whole of packages being installed.

In our package.json file, change ‘main’: ‘index.js’ to ‘main’: ‘app.js’

Create file ‘app.js’:

in your terminal, if you went node app.js, it will run the server on port 8080.

But whenever we make a code change, we have to restart the server and this becomes cumbersome. So let’s install nodemon.

npm i nodemon

Then in your package.json:

Now, in your terminal, Ctrl+C to get out of whatever is running.
Then npm run dev.
It will run the command as specified in our package.json and we get the server running with constant updates.

Putting in Routes

routes/posts.js

app.js

Install Middleware

npm i morgan

Installing Database

Create account in mLab, and create a database. Select default for everything, i.e AWS, server at Europe, and create submit. Then ‘create db user’, and create a username and pwd for the db’s user.

Then, in your project, create a file .env:

.env

npm i dotenv

npm i mongoose

app.js

post.js

post.js

Forkify Web app (part 4 – Building the recipe model)

forkify-Recipes

We create the model part, and then get the controller to use it:

First create the Recipe where we fetch the data from the backend. We dynamically assign properties title, author, image…etc to the data that we get back.

What you’ll notice is that the ingredients we get back are whole words. What we want to do is to parse ingredients words into a short-handed format. But in the end, we also want to put them into an array of objects. That way, we can pass the measurement, unit, and text.

src/js/Model/Recipe.js

We do the same thing for Recipe as we did for Search.
We get data from server. Parse it, and do some processing on it.

We also implement functionality for ‘load’ event.

src/js/index.js

Make sure we render the results from our fetch operation. We put the result into a list on the left. The result is basically an array of recipes.

src/js/views/searchView.js

Forkify Web app (part 3 – loader and pagination)

Loader

Loader is about using the CSS that is provided to you. We copy and paste the html into our js file. Since the style file is present, it will animate the loader.
We then call the renderLoader js function in the controller.

src/js/views/base.js

When the data fetched is finished, we then call the removeLoader. We basically find the element with the class name ‘.loader’ and then go up to its parent, and call removeChild on it.

src/js/index.js

Now just use them right before and after the fetching of your data result.

Pagination

Pagination is part of rendering the results that we fetched from the backend.

src/js/index.js

We need to modify our renderResults functionality. Before, we just a simple forEach that renders all results. Now we have to be more selective.

We need to know two things, the page we’re on and the number of results per page.

We calculate for start and end so that we can selectively extract those data to be displayed.

If we were to start on say page 1, and 10 results per page we need 0-9.
if we start on page 2, 10 – 19…
…etc.

for ‘start’, we just do: (page-1) * resPerPage
for ‘end’, we simply do: page * resPerPage

Notice we get 0, 10
10 – 20
20 – 30…

We then use slice to get the start/end – 1

so slice(0,10) means to get elements from index 0 to 9
slice (10, 20) means to get elements from index 10 to 19
…etc

which is exactly how we want to render our recipes.

src/js/views/searchView.js

for all elements in array A, see if any of it matches in array B.

Given an array of target data…

We want to see if an array of ids can be found in that target data.

Say a user selects these ids:

We want to see if the selected ids can be found in the target array:

Thus, you see that it looks through the target array on all the selected ids. If the ids match, then it saves it into an array and returns it to you:


output:

(2) [{…}, {…}]
0: {id: 136, providerName: “ATT”, providerID: 36, active: true}
1: {id: 138, providerName: “Bell”, providerID: 40, active: false}
length: 2
__proto__: Array(0)

You can also do it the other way, around, but it is not intuitive. You get every single target item and see if it exists in the toFind array.

It doesn’t fare very well as it forces you to go through every target item. If that target item is not found, undefined is returned and it sticks it into your result array. Thus, that is why we must use _.remove to removes those undefined. This is not the way to go.