Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

238 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ”ฅ TEJ Bootcamp

๐Ÿ’š Junior Phase

The junior phase will comprise of 10 sections, with each section taking roughly 1 week of classes.

Course material

Useful links

Junior Phase Schedule

  • You can use this spreadsheet to track your bootcamp progress. Click the link to make a copy, then enter your start date and expected study hours per week in the Timeline sheet. As you finish each course, update the Curriculum Data sheet with your completion date on the "Actual End Date" column. This will automatically revise the "Calculated End Date" column estimates for when you'll complete the bootcamp courses.

HTTP call

Chapters

Part 0-b

WE-WILL-LEARN:

  • HTTP call

PRE-WORK:

TO-STUDY:

LECTURE-VIDEO:

TO-DO:

Instructions for TO-DO

  1. create a new git repository called fullstackopen in your local computer
  2. create a repository in github to push your local fullstackopen
  3. create a folder called part0 inside fullstackopen
  4. create separate files to put your sequence diagrams for exercises 0.4 to 0.6

pure react, modern react dev setup, component, state, event handler

Chapters

Part 1-a: Introduction to React

WE-WILL-LEARN:

  • pure react
  • modern react dev setup

PRE-WORK:

TO-STUDY:

LECTURE-VIDEO:

  • Pure react
    1. Create folder structure and files
    • create folder pure-react, then src inside it
    1. Create index.html inside src
    • add script tag for React, ReactDOM, and index.js
    1. Create index.js inside src
    • use ReactDOM.createRoot, React.createElement, and render to create web application using pure react
  • Tooling with npm, prettier, eslint, vite
    1. Create folder structure and files
    • create folder tooling, then copy src from pure-react
    1. Toolings
    • create npm project by npm init -y
    • install Dev prettier, eslint, vite
    • setup config for prettier, eslint, and vite
    • install react, react-dom
  • Convert pure react to dev environment running from vite
    1. Move react and react-dom libraries to index.js
    2. Use type="module" in index.html
    3. Create vite scripts in package.json for dev, build, and preview
  • Using JSX
    1. Move components App and Hello to individual files
    • remember to import and export required things
    • make sure to start component name with Capital
    1. Convert React.createElement to JSX
    • rename all files with JSX to .jsx extension from .js
    • remove the imports that are not required for JSX
    1. Configure eslint to understand react and JSX
    • npm i -D eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react
    • update eslint config
    1. Please read Some notes section for common errors to avoid
    2. What can you render in JSX?

Instructions for the workshops shown in the LECTURE-VIDEOs

  1. Create a new repository called fullstackopen-workshops
    • create the repository in your local computer
    • create a repository in github to push your local fullstackopen-workshops
    • create a folder called part1 inside fullstackopen-workshops
  2. Please do the workshop at least once by yourself
    • read notes under LECTURE-VIDEO section
    • watch the lecture-video (if required)
    • read the material (if required)
    • then put today's workshop inside the part1 folder
    • refer to source code from lecture in part1-a branch if needed
    • continue future workshops under appropriate folder structures

TO-DO:

Instructions for TO-DO

  1. In the fullstackopen repository, create a folder called part1 inside fullstackopen
  2. Create folder called courseinfo inside of part1 to put your code for exercise 1.1-1.2
    • You can create courseinfo project either by using vite, as we did for the class today. You can clone this starter kit
    • Or you can create courseinfo project using create-react-app as described in the introduction to react section of the course

note-1: If you are cloning the starter kit, delete the .git directory inside the clone. note-2: See this example exercise repository for folder structure. Further details can be found with the exercise instructions

Part 1-b: Javascript

WE-WILL-LEARN:

  • Javascript concepts

TO-STUDY:

LECTURE-VIDEO:

  • Array methods in React
    1. Create a react project that says hello to many people
    1. In App create an array of objects of people to say hello to
    • a person object can have the properties for firstName, lastName, id etc.
    1. Display hello to each person
    • for each element in array, call SayHello component through the map method
      • pass entire person object to SayHello
      • in SayHello, destructure props
      • write a component helper function to return combination of firstName, lastName
      • use the helper function in the JSX returned by the component
    • If array is empty, display appropriate message
      • use if else condition
      • use ternary
return (
  <div>
    {peopleArray.length > 0 ? (
      peopleArray.map((value) => <SayHello person={value} key={value.id} />)
    ) : (
      <h1>No records found</h1>
    )}
  </div>
);
  • add filter method to say hello only to people with id greater than 2

Instructions for the workshop shown in the LECTURE-VIDEO

  1. In the fullstackopen-workshops repository created in part1-a
    • create the workshop project using-array inside the folder part1
  2. Please do the workshop at least once by yourself
    • read notes under LECTURE-VIDEO section
    • watch the lecture-video (if required)
    • do today's workshop in the using-array folder
    • refer to source code from lecture in part1-b branch if needed

TO-DO:

Instructions for TO-DO

  1. In the fullstackopen/part1/courseinfo repository, continue to put your code for exercise 1.3-1.5
Part 1-c: Component state, event handlers

LECTURE-VIDEO:

  • Component manual re-render
    1. Create a react project that updates the count
    • create project counter-app inside part1
    • create component App and jsx file index.jsx
    1. Update the count in some set interval
    • use setInterval to update count, and also call the render manually to re-render the app
  • React state
    1. Use useState hook to make a stateful component inside App component
    • convert the counter to a state using useState
    • use setTimeout to call a function after 1 second that changes the value of counter state
    • remove the manual call to render
  • React event handling
    1. add a button to increase the count
    • add button element
    • include an onClick event handler to the button. The event handler has to be a function, not function execution!
    1. Refactor components for display and button
    • refactor Display component
      • call Display from App and also pass it the counter state
    • refactor Button component
      • call it for plus, minus, and zero by passing appropriate event handlers

TO-DO:

Part 1-d: Complex state, debugging React apps

WE-WILL-LEARN:

  • a more complex state
    • array, object in state: don't mutate state!
  • conditional rendering of component
  • debugging React apps

LECTURE-VIDEO:

  • Using object, array in state
    1. Create a copy of counter-app in part1 directory
    • first delete node_modules folder from counter-app
    • cp -r counter-app double-counter
    1. Put two counters
    • put the state of the left and right counter in an object
    • put the state of click history in an array
    • lets put the total number of clicks in a state
  • Conditional rendering in component
    1. Create a new History component that shows the click history
    2. Conditionally show the history only when there is history
    • otherwise, show another message
  • React debugging, and notes on hooks
    1. Do the following for debugging
    1. Rules of hooks (useState, useEffect etc.)
    • only call hooks inside functional components
    • do not call hooks from
      • inside of a loop
      • a conditional expression
  • Exercise 1.1 to 1.14 guide

TO-DO:


Modules, forms, getting data from server, altering data in server

You can refer to the workshop code solutions here

Chapters

Part 2-a: Rendering a collection, modules

PRE-WORK:

WE-WILL-LEARN:

  • rendering collection [Array or Object]
    • don't mutate state! especially if state is Array or Object
  • Array.map
  • Array.reduce
  • most common problems in React up to this point
    • the props are expected to be of a different type,
    • or called with a different name than they actually are, and destructuring fails as a result

LECTURE-VIDEO:

  • Using Array.map to show data in React
    1. Create react project notes-app
    • create directory part2
    • create react project notes-app inside part2
    • pass array of notes from index.jsx to App.jsx
    • in App.jsx access the array data using indices
    1. Access the array using map method
  • Using key in React lists, and further debugging notes
    1. Use the key attribute when rendering array
    • understand how map method is working
    • using index vs id for key attribute
    1. Refactor the code
    • destructure the props
    • create the components directory inside src
    • refactor components and put them in components directory
      • note that the key attribute is now required in the component

TO-DO:

Part 2-b: Forms

WE-WILL-LEARN:

Main concepts

  • controlled HTML input component
  • filtering displayed elements

Side notes

  • form onSubmit event handler needs event.preventDefault()
  • form in App
  • controlled HTML component: using onChange
  • ternary expression
  • Array.filter

LECTURE-VIDEO:

  • Adding a controlled HTML input component to add notes
    1. Create a state to keep track of notes array
    2. Add a form in JSX to add a note
    3. Put an onSubmit event handler to the form
    4. Add a controlled HTML input component to capture the entry of a new note
    • add a new state to store the new note
    • use the state as the input value
    • add an onChange event handler on the input
    1. Complete onSubmit to add new note to notes array
  • Filtering displayed notes
    1. Add state to keep track of showAll
    2. Add a notesToShow variable to keep notes to show based on showAll state
    • if showAll is true, then notesToShow is same as notes
    • else, notesToShow only has importants notes
    1. Add functionality to toggle between all and important
    • add button with text for action
    • add onClick to button to toggle showAll state

TO-DO:

Part 2-c: Getting data from server

WE-WILL-LEARN:

LECTURE-VIDEO:

  • Setting up json-server as our backend server
    1. Create the db.json file with array of notes
    2. Install json-server as dev dependency
    npm install json-server --save-dev
    
    1. Start the json-server
    npx json-server --port 3001 --watch db.json
    
    1. Include json-server start command in package.json scripts
    2. view the output on web browser
    • if required, install the JSONVue extension
  • Understanding the useEffect hook
    1. in App.jsx, create a useEffect hook so that it is only called on first render
    2. update the useEffect hook so that it executes each time the showAll state changes
  • Using Axios in frontend to access data from backend
    1. Install axios as dependency
    npm install axios
    
    1. Read the data from json-server from our app using axios
    • start json-server in one terminal
    • start the app in another terminal
    • add code for axios.get in App.jsx inside the useEffect hook
    • modify useEffect so that it is called only on first render of the component

TO-DO:

Part 2-d: Altering data in server

WE-WILL-LEARN:

Side notes

  • Array.find
  • Review
    • Array.map
    • Array.filter

LECTURE-VIDEO:

  • Using axios.post to create note in backend
    1. Add axios.post code inside the event handler responsible for creating new note
    • a brief look at REST API
    • remove the id from your new note object, because now the REST API should create the id
    • update your notes state with the returned note object
    • now, even if you refresh, the newly added note is still present
  • Using axios.put to update note in backend
    1. Add button to toggle the important field of note
    • in Note component, add a button to toggle importance
    • what will be the onClick event handling function on the button?
    1. In the event handling function, add logic to update the data in server, and in state
    • first, find the note from our state
    • then, create a new object with the changed state of the note
      • don't mutate state directly!
    • send the new object using axios.put to update data in server
    • change the state of notes to reflect the updated note
  • Refactoring axios services
    1. Create a services folder inside the src folder
    2. Create notes.js fild inside services
    3. Create a getAll, create, and update functions specifically only for the server functions
    • return a promise that returns the destructured data
    • use these new functions in App.jsx to interact with the server
  • Handling axios errors in catch block
    1. In getAll note service, add a fake note to the array returned from server
    2. Add a catch block to catch any error to the call to update
    • when we try to update a note in the server that does not exist, json-server will throw an error
    • print the error in the catch block
    • if the status code is 404, it means the data does not exist
      • remove the data from notes state if data does not exist in server
      • show an alert with proper error message

TO-DO:

Part 2-e: Adding styles to React app

WE-WILL-LEARN:

  • adding styles to React app
    • 2 methods
      • importing style file into JS project
      • inline styles in JSX
    • CSS rules = selector + declerations
    • class selectors in JSX
  • error message in it's own React component
    • activating error component by setting error message

LECTURE-VIDEO:

  • Inline styles
    1. In App.jsx, define a new variable whose value is an object with css style
    • note that the CSS properties are written in camelCase, not hyphenated as in css file
    1. In the h1 element in the JSX, create a new attribute called style and assign it the above variable
  • Using a css file to define a style
    1. Create a css file index.css in the src directory
    2. Define a style for class .redbackground
    3. Import index.css in index.jsx
    4. In App.jsx, use the redbackground class in the input html element
  • Creating dynamic error message from catch block
    1. Create a new component called Notification
    • define an error class in css file to use in the Notification component
    1. Define a new state to put the error message with an initial value of null
    2. In the catch block for error handling, add code to display the error message in the Notification component
    • in the catch block, set the error message state with the error message
    • after a certain amount of time, set the error message back to null
  • Debugging openweather map api key

TO-DO:


You can refer to the workshop code solutions here

Chapters

Part 3-a: Node.js and Express

WE-WILL-LEARN:

  • creating a simple Node project that runs in Node environment
  • running a simple web server
  • using Express library to build a more developer friendly web server
  • using nodemon to run node
  • defining routes in Express
    • CRUD functionality in Express routes
  • Middleware
    • writing our own middleware

Side notes

LECTURE-VIDEO:

  • Creating a simple express server
    1. Create new project notes-server
    • create an npm project inside by npm init -y
    • create an http server that shows the text 'Hello world', listening on port 3001
    1. Serve notes as JSON data using http server
    • create a notes variable with the notes array
    • convert the http response to type application/json
    • JSON.stringify the notes array in the response
  • Using express for serving on the '/api/notes' route for a 'get' method request
    1. Install express library
    • modify code to use express library
    1. Modify to express route to server array of notes on /api/notes url for get request
    2. Install nodemon as dev dependency to run node server by hot reload on code changes
  • Side note on REST and JSON
  • Creating the '/api/notes/:id' route for a 'get' method request
    1. Create a new get route at /api/notes/:id
    2. Respond with the json object of the note at that id
    • please note that the request.params always comes as a string
    1. If no notes are available at the id, then set status to 404 and return a friendly error message
  • Creating the /api/notes/:id route for a delete method request
    1. Create a new delete route at /api/notes/:id
    2. Respond with 204 status code, and no body
    3. Install REST Client extension
    4. Create file requests/my_requests.rest to store the REST requests
    • call the delete method on the REST endpoint
    DELETE http://localhost:3001/api/notes/2
    
  • Creating the '/api/notes' route for a 'post' method request
    1. Create a new post route at /api/notes
    2. Use express.json() to read json objects in the request
    3. Use the json object in request to create a new post in the backend
    4. Respond with status 201 created and return the newly created note object
  • Creating middleware
    1. Create a middleware at the top of the express server to log method, path, and body
    2. Creat a middleware at the end of the express server (just before app.listen) to send a 404 not found to all paths that are not handled by the app

TO-DO:

Part 3-b: Deploying app to internet

WE-WILL-LEARN:

Side notes

LECTURE-VIDEO:

  • Use notes-server instead of json-server
    1. Start notes-app
    2. Start notes-server
    3. Change baseUrl in notes-app to the url of our notes-server
    4. Configure CORS in notes-server so that app and server work from different origins
    • install cors library
    • use cors library in server's index.js file
  • Serving frontend static files from node server
    1. Build react app for serving from web server
    2. Include the build folder in your node application
    3. Instruct node server to serve the static files from the build folder
  • Modify frontend backend code to run in cloud
    1. In react app, change the baseurl to a relative url
    2. In node server, read the PORT value from environment if available
  • Deploy fullstack app to Render
    1. Create a render account at https://dashboard.render.com/register
    • sign up using GitHub
    1. Create a new Web Service
    • connect to the proper github repository
    • configure Root Directory, Build Command (npm install), and Start Command
    1. Push your code to GitHub
    2. In notes-server, streamline notes-app build and deploy process
    • add npm script to build the react app and copy it to server repo
      • remove the existing dist folder
      • cd to notes-app
      • build notes-app
      • cp the dist folder from notes-app to notes-server
    1. Add proxy to vite config of notes-app so that we can use relative url in react dev environment
    server: {
      proxy: {
        "/api": {
          target: "http://localhost:3001",
          changeOrigin: true,
          secure: false,
        },
      },
    }
    

TO-DO:

Part 3-c: Saving data to MongoDB

LECTURE-VIDEO:

  • Introduction to mongodb
  • Setting up mongo database in mongodb.com
    1. Create a free account in mongodb.com
    1. Create database userid and password
    • create project
    • build database using free option
    • choose the username password option for authentication
    • finish database creation
    1. Set network setting to allow access from anywhere
    • go the 'network access'
    • edit and select 'allow access from anywhere'. note - this is only for development!
    1. Get the connection string to your database
  • Using mongoose to set up a practice application
    1. npm install mongoose
    2. Create a new mongo.js file in your repo to create practice application
    1. Run our code from terminal to create a collection and data in noteApp database
    • run node mongo.js password, this will create the note data in test database, in notes collection
    • delete the test collection
    • add noteApp to the db connection string
    • run node mongo.js password again, this will now create the note data in noteApp database
    1. Write code to fetch data frome notes collection using the Note model
    • in mongo.js, comment out the note creation code
    • add code to get the data
    • run node mongo.js password again
  • Connect the notes-server to the database
    1. Fetch db connection string from environment
    • install npm library dotenv that will allow us to convert variables from .env file to process.env variables
    • for localhost
      • create a .env file to store the db connection string (add .env file to .gitignore)
      • in .env file, enter db connection string to variable MONGODB_URI
      • in index.js file, use dotenv library to read env variables
    • for render: configure db connection string in render Environment
    1. Create separate module to put database configuration
    2. Get data from database in the /api/notes route for get method
    3. Modify the returned data from mongoose to show the id field instead of _id, and hide the __v field
  • More node express routes configured through database
    1. Rewrite /api/notes route for post method
    2. Rewrite /api/notes/:id route for get method
    3. Error handling
    4. Moving error handling to middleware
    • make sure middlewares are loaded in proper order
    1. Rewrite /api/notes/:id route for delete method
    2. Write /api/notes/:id route for put method

TO-DO:

Part 3-d: Validation and ESLint

LECTURE-VIDEO:

  • Mongoose schema validation
    1. Create a mongoose schema validation for content field in noteSchema
    2. In the note post route, catch the error in note.save
    3. Put the error handler in the error handling middleware
    4. Catch and display the error in the notes react app
  • Mongoose schema validation while updating
    1. In the note update route, configure it to also throw schema validation errors
    2. Why schema based validation is better than logical error handling in code
  • Linting setup and configurations
    1. Install eslint as a dev dependency
    2. Setup config file for eslint
    • change env browser to node
    1. Setup the VSCode extensions for eslint
    2. Create script to run eslint
    3. Create eslint ignore config file .eslintignore
    • include the dist folder
    1. Create eslint rule for
    • eqeqeq
    • show warning for console.log
    1. Difference between formatting (prettier) vs code linting (eslint)

TO-DO:


You can refer to the workshop code solutions here. Look at the appropriate branch (e.g. look at branch part4-1 for Part 4-a)

Chapters

Part 4-a: Structure of backend application, introduction to testing

LECTURE-VIDEO:

  • Code refactoring
    1. Refactor config, logger, and middleware to utils folder
    2. Split the app code from index.js to app.js
  • Refactoring Node express Router and Note model
    1. Refactor all the notes routes to controllers/notes.js
    • use require('express').Router()
    1. Refactor the notes schema and model specific code to models/note.js
  • Unit testing Node application
    1. Install jest in dev dependency (npm install --save-dev jest)
    2. Define npm script to run jest and specify the execution environment is node
    3. Create a file, utils/for_testing.js with simple functions to test
    4. Create unit testing file tests/reverse.test.js with tests for reverse function
    • run it
    • make one test case fail to analyze the jest error message
    1. Configure eslint to ignore the jest commands in the test file
    2. Create unit testing file tests/average.test.js with tests for average function
    • run it and analyze the failed test case
    • fix the failed case
    • notice the describe block

TO-DO:

Part 4-b: Testing the backend

LECTURE-VIDEO:

TO-DO:

Part 4-c: User administration

PART 4-c: User administration

WE-WILL-LEARN:

  • Creating users with passwords in the Mongo DB database
    • using bcrypt for one way hashing of password to store in database
    • using Test Driven Development (TDD) method
  • Associate a Note to a User
    • put a notes array field into User
    • put a a user field into Note
    • association is enforced by mongoose library, not by Mongo DB
  • Using the mongoose populate method

LECTURE-VIDEO:

TO-DO:

Nothing!!

Part 4-d: Token authentication

PART 4-d: Token authentication

LECTURE-VIDEO:

TO-DO:


Chapters

Part 5-a: Login in frontend

LECTURE-VIDEO:

TO-DO:

Part 5-b: props.children and proptypes

LECTURE-VIDEO:

TO-DO:

Part 5-c: Testing React apps

WE-WILL-LEARN:

We will learn unit testing a React component. We will learn to test:

  • a component will render what we expect it to render
  • a component will call the correct function passed as a prop when a button is clicked
  • a component will re-render correctly when a button is clicked
  • a component will call a function with the correct argument when a button is clicked

LECTURE-VIDEO:

TO-DO:

Part 5-d: End to end Testing

LECTURE-VIDEO:

TO-DO:


Chapters

Part 6-a: Flux-architecture and Redux

WE-WILL-LEARN:

  • create redux store
  • pass the redux store to app via provider

LECTURE-VIDEO:

  • Create a counter app that uses redux
    1. Setup the application
    • clone the react starter repo
    • rename to redux-counter
    • cd redux-counter
    • rm -rf .git
    • npm i redux
    1. Create a simple counter app using useState in index.js (we won't be using App.jsx yet)
    • create a reducer, counterReducer in this case. the reducer does the work similar to setState
    • create a store, by using createStore and passing it the reducer
    • use store.getState() to get the store (like the state)
    • use store.dispatch(action) to modify the store (like calling setState)
      • action is an object with type key, and optionally data key
    • use store.subscribe(React Component) to rerender component when store changes
  • Create a note app that uses redux
    1. Setup the application
    • clone the react starter repo
    • rename to redux-note
    • cd redux-counter
    • rm -rf .git
    • npm i redux
    1. Setup redux in index.jsx for note app
    • create a reducer, noteReducer in this case. the reducer does the work similar to setState
    • create a store, by using createStore and passing it the reducer
    • use store.getState() to get the store (like the state)
    • use store.dispatch(action) to modify the store (like calling setState)
      • action is an object with type key, and data key
    • use store.subscribe(React Component) to rerender component when store changes
    1. Add functionality to toggle importance using Test Driven Development method
    • setup test environment
      • install required packages
      • configure .babelrc file
      • add test script to package.json
      • add jest environment to .eslintrc.json
      • add deep-freeze library to test for immutability
    • move the noteReducer to its own file at reducers/noteReducer.js
      • export store and the reducer
    • in the test file noteReducer.test.js, put test case for adding a new post
    • add another test to toggle the important field
  • Add functionality to add new note
    1. Add form to add note
    2. Add onSubmit handler that calls store.dispatch for adding note
    3. Add frontend for toggling
    • add onClick call to toggleImportance function from each note display
    • write the function toggleImportance to call store.dispatch
    1. Write action creators for adding note, and toggling importance
    • write an action creator called toggleImportanceOf that creates the action to dispatch for toggling importance
    • write an action creator called createNote that creates the action to dispatch for adding note
  • Refactor note app to use Provider
    1. Put the reducer in the reducers/noteReducer.js file
    2. Also move the action creators to reducers/noteReducer.js
    3. Move the app component to App.js
    4. npm install react-redux
    5. Modify the store related code in index.js, pass the store to Provider and wrap the App with it
    • in index.js import Provider
    • wrap App with Provider with store
    1. Modify App to read store from Provider
    • useSelector to get access to the store
    • useDispatch to get access to dispatch
    1. Now even if we refactor add new note form to its own component, we don't need to pass the store from App; the store can be directly accessed by all the components
    • refactor creating new note into its own component

TO-DO:

Part 6-b: Many reducers

WE-WILL-LEARN:

  • using Combined reducers to combine multiple reducers
  • using Redux toolkit to simplify and streamline the use of Redux stores
  • using Redux devtool to debug and help develop redux

LECTURE-VIDEO:

  • Add state for visibility filter by putting it in another reducer using Combined reducers
    • note that NewNote and Notes components have been refactored from App component
    1. Initialize notes state with two notes in noteReducer
    2. Create visibility filter to show all / important notes
    • put radio buttons with onChange event handler
    • note that name is same for the radio inputs to form a button group
    • use useState to store the state of visibility in App component
    • pass the state as prop to Notes
    • in Notes use the prop to show the desired notes
    1. Create new reducer filterReducer to store value of filter
    • put the reducer function filterReducer
    • create action creator filterChange
    1. Modify index.js to combine the reducers filterReducer and noteReducer
    • import combineReducers from redux
    • use combineReducers to combine the two reducers
    • change createStore to take the combined reducer
    1. Change the code to use redux instead of useState
    • modify Notes.js to now only read the notes key from the state
    • dispatch to the reducer when radio button is clicked
    • modify Notes.js to use filter from redux store instead of useState
    1. Create separate component for VisibilityFilter
    • in App use the VisibilityFilter component to display the filter
  • Using Redux Toolkit
    1. Install the Redux Toolkit
    • npm install @reduxjs/toolkit
    1. Modify index.js to use toolkit
    • import and use configureStore to create store, which will replace combineReducers and createStore
    1. Modify noteReducer.js to use toolkit
    • use createSlice to refactor the reducer and action creators
    • use export using toolkit
    • how is action.type derived?
  • Using Redux devtool
    1. Install devtool from https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd
    • this only works if using Redux Toolkit
    1. Open the Redux devtool window
    2. See the change in state for all the actions
    3. Dispatch an action from the toolkit

TO-DO:

Part 6-c: Communicating with server in a redux application

WE-WILL-LEARN:

  • dispatch can also take a function. if we pass a function to dispatch, then dispatch will execute that function by passing dispatch as the first argument

LECTURE-VIDEO:

  • Getting notes from the backend while using Redux
    1. Create db.json file in root folder, and put some data
    2. Install and run json server
    • npm install json-server --save-dev
    • in package.json add script to run json-server
    • npm run server
    1. Create service to fetch data from backend
    • npm install axios
    • create file services/notes.js to fetch data using axios from the backend
    1. Get initial data from backend
    • in noteReducer change initial state to empty array
    • in noteReducer add an action to append a single note
    • in noteReducer add an action to set all the notes
    • in App, create a useEffect to load the initial data from json-server
  • Storing a note to the backend while using Redux
    1. When creating note, add functionality to also add the new note to backend
    • in services/notes.js, add function to create note in backend
    • in NoteForm component, modify to call the service to backend
    1. You can also change the toggle importance functionality to also update backend
  • Using thunk to move server connection logic to Redux action creator
    1. Modify the initial notes loading functionality to move server communication to a thunk
    • change App useEffect to just dispatching return value of initializeNotes action creator
    • in noteReducer, create a new thunk initializeNotes that will:
      1. get all notes from the server
      2. then dispatch the notes to Redux store
    1. Modify the createNote functionality to move server communication to a thunk
    • change NoteForm component back to just dispatching return value of createNote action creator
    • in noteReducer, replace the createNote action creator with createNote thunk that will:
      1. call RestAPI to create a note in the server
      2. then dispatch the new note to Redux store
    1. Refactor Redux store creation
    • create store.js in root folder
    • move all Redux store creation code from index.js to store.js
    • in index.js import the store to pass to App

TO-DO:

Part 6-d: React Query, useReducer and the context

WE-WILL-LEARN:

LECTURE-VIDEO:

  • Using React Query
    1. Setup for using React Query
    • npm install @tanstack/react-query
    • setup index.jsx to use React Query
    1. Retrieve the notes in the App component
    • start json-server
    • use useQuery
    1. Refactor the server call to it's own requests file
  • Adding new note via React Query
    1. Add function createNote in requests to post note to server
    2. In App add useMutation code for adding new note
    • call the mutate method to post the new note to server via React Query
    • invalidate the notes result, so that React Query re-fetches the notes
    1. Add functionality to toggle importance
    • add toggle function to call server in requests
    • add mutation code in App when note is toggled
  • Optimize React Query code to minimize calls to server
    1. Modify onSuccess of new note creation to manually add new note to React Query state
    • add newNote parameter to callback function of onSuccess
    • getQueryData for notes (queryKey has to be an array)
    • manually setQueryData for notes adding the newNote
    1. Turn off refetchOnWindowFocus where not required
    2. React Query is server-state library, Redux is a client-state library
  • useReducer and context
    1. Implement useReducer for a simple counter app
    • create a new CounterApp file
    • render CounterApp from index.jsx
    1. Use context to pass the state
    • create a new file CounterContext, and use createContext to create a context for the counter state
    • in CounterApp use the context provider from CounterContext to provide the counter state to CounterApp
    • use useContext of CounterContext to read the value provided by the context provider in all required components
    1. Refactor the code
    • move all counter reducer related code to CounterContext.jsx file
    • in index.jsx, wrap the CounterApp with CounterContextProvider
    • refactor useContext code into CounterContext to fetch the state and the dispatch separately
    • note that useCounterValue and useCounterDispatch are custom hooks
  • Choosing the correct state management solution

TO-DO:


Chapters

Part 7-a: React-router

WE-WILL-LEARN:

  • How to use react router for client side routes

LECTURE-VIDEO:

  • Implement react router
    1. Create new project react-router using react-start-kit
    2. Create simple SPA with menu
    3. Install react router
    4. Write code to use simple react router
    • use BrowserRouter to encapsulate all code that will use router
    • create Link for the required links
    • use Routes and Route to handle the links to components
  • Add parameterized route and useParams to read the parameter
    1. Show notes
    • create a Notes.jsx component to show all notes
    • hardcode notes array with some notes in App.jsx and pass as props to Notes.jsx
    1. Create parameterized route for note/:id with useParams
    • update Notes component that creates Link to individual notes based on id
    • create a new Route to handle note/:id route
    • create Note component with useParams that will display individual note
  • Add useNavigate to programmatically navigate to a url
    1. Create login route
    • create a user useState to keep track of logged in user
    • if no user state, then show link to login that is a link to login route
    1. Create Login component
    2. Create a new route in App.jsx to direct the login path to Login component
    3. Modify Login component to handle user login
    • pass the setUser from App to Login
    • create a login form that takes a username and sets it to user state
    • use useNavigate to navigate to / route after logging in
    • in App.jsx use Navigate component in users route to conditionally redirect to login route when not logged in
  • Use useMatch for better parameterized route
    1. Move BrowserRouter component to index
    2. In App, use useMatch to get the notes/:id parameter to find the note
    3. Pass and read the single note object to the Note component
  • Build and deploy the react router app to node server

TO-DO:

Part 7-b: Custom hooks

WE-WILL-LEARN:

  • Creating and using custom hooks
    1. Custom hooks follow the same rules as react hooks
    2. Create custom hooks when you need complicated logic with react hooks that can be re-used

LECTURE-VIDEO:

  • Create custom hook for counter application
    1. Create new project using react-start-kit
    2. Create simple counter application
    3. Move counter logic to custom hook useCounter in hooks folder
    • make sure the name of custom hook always starts with use
    1. Use useCounter for two different counters in the same App component
  • Using custom hook for forms
    1. Create an App with forms
    2. Create useField custom hook in hooks folder
    3. Use it in a form field
    4. Use the spread operator
    • to pass props to component from object with same named keys
    • to pass attributes to elements from object with same named keys

TO-DO:

Part 7-c: More about styles

WE-WILL-LEARN:

  • use of readymade UI libraries for styling in react

LECTURE-VIDEO:

  • React Bootstrap
    • npm install react-bootstrap
    • add a link for loading the CSS stylesheet for Bootstrap inside of the head tag in the public/index.html file
    • container <div className="container">
    • import { Table,Form,Button } from 'react-bootstrap'
    • render list of notes as a table
    • improve the form in the Login view with the help of Bootstrap Form
    • stlye notification message using Alert component
    • navigation structure
  • Material UI
    1. Material UI
    • install the library with command {npm install @mui/material @emotion/react @emotion/styled}
    • use Material UI to make the same changes that were made using react-bootstrap
    • each component has to be imported separately
  • Other styling options
    1. Styled Components
    • npm install styled-components
    1. Other UI frameworks

TO-DO:


Chapters

Part 13-a: Using relational databases with Sequelize

WE-WILL-LEARN:

  • Using Relational Database (Postgres) instead of mongoDB for the notes app
  • Using Sequelize ORM to create JS Model for Postgres tables

USEFUL-SQL-COMMANDS:

  • Create a table called notes
CREATE TABLE notes (
    id SERIAL PRIMARY KEY,
    content text NOT NULL,
    important boolean,
    date time
);
  • Insert a row into notes table
insert into notes (content, important) values ('Relational databases rule the world', true);
  • Read rows from notes table
select * from notes;
  • Remove the table notes
drop table notes;

LECTURE-VIDEO:

  • Setup the relational database
    1. Create a Postgres DB in render
    2. Install Postgresql extension by Chris Kolkman to connect to the database
    • make sure to correctly setup ssl
    1. Use the Postgresql extension
    • create table notes in the database using the extension
    • insert a few rows into the table
    • check the table and the inserted rows with the extension
  • Create notes-server to connect to relational database
    1. Create part13/notes-server
    • make the folder notes-server
    • npm init -y to create a new npm project
    • npm install express dotenv pg sequelize
    1. Add the DB connection string to .env file
    2. Write api to read all notes from db
    • create index.js
    • write the api/notes for get method to read all notes from DB using select query
  • Using Sequelize ORM
    1. Use Sequelize ORM to rewrite api/notes get method
    • create a Model for Note
    • use the Note model to get all notes from DB
    1. Add api to create a single note with simple error handling
    • remember to use middleware to correctly read json data sent to server
    • note the difference between create and build
    1. Call the single note creation api
  • Additional notes on relational database
    1. Creating database tables automatically using the Sequelize model
    2. Add api to read a single note
    3. Add api to modify a note
    4. Printing the objects returned by Sequelize to the console
    • using toJSON
    • using JSON.stringify

TO-DO:

Part 13-b: Join tables and queries

WE-WILL-LEARN:

  • User management in sequelize
  • Joining data from two tables in sequelize
  • Using query parameters in REST API

LECTURE-VIDEO:

  • Refactoring the code
    1. Start with util directory
    • create config.js to read configurations from environment
    • create db.js to put DB boilerplate code
    1. Refactor route handling to controllers
    • move notes routes to controllers/notes.js
    • modify index.js to use the notes controller for all /api/notes requests
    1. Refactor models
    • move Note model to models/note.js
    • create models/index.js to centralize all models related code
    1. Move db connection code to util/db.js file
    • add a function to test the db connection, then call it before starting app
    1. Refactor notes controller
    • put repetitive code to middleware
    • call middleware in the routes where required
  • Create user login
    1. Create User model
    • create models/user.js for User model
    • include the User model to models/index.js
    1. Create routes for user management
    • create controllers/users.js
    • create controllers/login.js
    • add SECRET in .env and util/config.js
    • npm install jsonwebtoken
    • include the routes in index.js
    1. Use REST Client to test login
    • create user from the REST Client
    • login with user and get token
  • Add user to note
    1. Add relation between User and Note
    • in models/index.js add the foreign key from User to Note
    1. Modify note post route to also insert logged in userId
    • in controllers/notes.js, add tokenExtractor middleware
    • use tokenExtractor to decode the the userId from token
    • include the userId while inserting a new note into the DB
    1. Use REST Client to create note using token
    • call api to create note by passing token and note object
  • Cleaning up & more queries
    1. Modify get notes to return the full user
    2. Modify get users to return notes created by user
    3. Modify get notes to use query parameters to fine tune sequelize query
    • include the important field in the api call
    • include the option to show all results when important is not specified in the query
    • modify Note model to not allow null for important
    • include searching text inside content field
    • exclude where clause when not required

TO-DO:

Part 13-c: Migrations, many-to-many relationships

WE-WILL-LEARN:

  • How to properly migrate database (create / update database schema)
  • Through table, and many-to-many relations
  • Other sequelize functionalities

LECTURE-VIDEO:

  • Data migration the proper way
    1. Create the initial data migration script
    • create the file migrations/20230929_00_initialize_notes_and_users.js
    1. Write code to run migrations
    • npm install umzug
    • add migration code to util/db.js
    • remove the sync code from models/index.js
    1. Run the first migration
    • drop all existing tables
    • start the node server
  • Admin user and user disabling
    1. Create a user
    2. Create a few notes
    3. Stop the server
    4. Create migration file with new fields
    • create the file migrations/20230929_01_admin_user_disabling.js
    1. Make corresponding changes to models/User
    2. Start the server
    3. Make changes to loginRouter to disallow logging in for users with disabled field set to true
    4. Try logging in with disabled user
    • create a disabled user
    • using REST Client, try logging in with the disabled user vs. a not-disabled user
    1. Create route for admin user to change status of a user
    • make changes in controllers/users
    • move tokenExtractor from controllers/notes to util/middleware.js
    • import tokenExtractor in both controllers/users and controllers/notes
    1. Create admin user that can change disabled user to enabled user
    • convert user 1 to admin
    update users
    set admin=true
    where id=1;
    • login with user 1
    • use token from user 1 to update user 2 to enabled
    1. Create rollback functionality to undo migration
    • modify util/db to put rollback function
    • create util/rollback.js that calls the rollback function
    • add script in package.json to run the rollback file
  • Creating many-to-many relationship to allow users to be part of multiple teams
    1. Create migration for teams and memberships tables in file migrations/20230929_02_add_teams_and_memberships.js
    2. Make models form Team and Membership to reflect updated schema
    3. Update models/index to define the new relationships
    4. Create some teams
    5. Add users to teams in the membership table
    6. Now change get users route to include teams of the users, and excluding through table data
    7. Understand the object returned by sequelize such as in the code below:
    const user = await User.findByPk(1, {
      include: {
        model: Note,
      },
    });
    user.notes.forEach((note) => {
      console.log(note.content);
    });
    1. Creating new return object when required shape is different from object returned by database
  • Revisiting many-to-many relationships
    1. Create migration for user_notes through table to associate many users with many notes
    2. Create userNote model
    3. Modify models/index for the many to many relation
    4. Modify get users route to return users' notes and user marked notes
    5. In the route, add the author of the note
  • Concluding remarks
    1. Lazy fetch based on query parameter
    • Modify get user so that it fetches the user's teams only if the query parameter teams is set in the request
      • note how getTeams method is generated by sequelize based on defined relationships
    1. Defining default scopes for model
    • in User model, exclude disabled users by default
    • also define admin scope
    • includ admin scope in sequelize query with User.scope('admin').findAll()
    1. Adding methods to sequelize models
    • add instance method numberOfNotes
    • add class method with_notes
    1. Repeatability of models and migrations
    • generating migration and model using sequelize command line tool

TO-DO:


Chapters

Part 9-a: Background and introduction

WE-WILL-LEARN:

LECTURE-VIDEO:

  • Main principles
    1. Typed superset over JavaScript
    • Compiles to plain JavaScript
    • Type annotations
      • input type of function
      • output type of function
    • Typing
      • explicit typing
      • inferred type
    1. Lifecycle of TypeScript
    2. Why to use TypeScript
    • type checking
    • static code analysis
    • code level documentation
    1. What TypeScript does not do
    • external libraries with no types
    • runtime validations

TO-DO:

Nothing to do!

Part 9-b: First steps with TypeScript

WE-WILL-LEARN:

LECTURE-VIDEO:

  • Setting up TypeScript tooling for Node project
    1. Manual setup
    • create folder
    • create npm project npm init -y
    • install libraries npm install --save-dev ts-node typescript
    • add script inside package.json
    1. Create our first TypeScript function, with plain JavaScript
    • create a file multiplier.ts
    • run it with npm run ts-node -- multiplier.ts
    1. Let's use TypeScript
    • give input types for function parameters
    1. Create custom type
    • create union type
    • see type suggestion
    • try using a not accepted argument
    1. Add return type
    2. Throw error when required
    • catch the error without putting any type
    • catch the error as unknown
      • then requires Type narrowing to access error.message
  • Putting TypeScript in Express server
    1. Change tsconfig.json
    2. Configure script
    3. Create index.ts file
    4. Run it
    • change config to make it work
    • change back config
    1. Types for express
    • convert require to import
    • add required types to make code work
      • npm install --save-dev @types/express
    1. Other config related errors
    2. Install ts-node-dev
    • npm install --save-dev ts-node-dev
    • add package.json script
  • Add api endpoint for calculate
    1. Add code for /calculate endpoint
    • export and import the multiplicator function
    • use it in the api
    1. Difference between explicit and implicit any
    2. Disallow explicit any
    • npm install --save-dev eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser
    • configure .eslintrc
    • add script to package.json
    1. Setup more eslint rules
    • modify .eslintrc
    • fix the unsafe any issues
    • do some code level validation to sanitize data
    1. Using type assertion
    • import type Operation
    • use it to assert the op that is posted to calculate api
    • we can now remove the eslint warning, but this could cause runtime errors

TO-DO:

Part 9-c: Typing an Express app

WE-WILL-LEARN:

LECTURE-VIDEO:

  • Setting up production grade project
    1. Initialize a project using TypeScript
    • create directory flight_diary
    • cd flight_diary
    • npm init -y
    • npm install typescript --save-dev
    • add script run typescript
    • create tsconfig.json by initializing typescript
    1. Customize to our needs
    • configure tsconfig for our needs
    • install required additional packages
    • create .eslintrc
    • install and configure ts-node-dev for dev
    1. Get a basic node server working
    • Create index.ts
    • Build the project
    • Eslint ignore the js files
    • Create and run script from the compiled build folder
  • Start coding
    1. Create a directory structure
    2. Make a new diaries route
    • create diaries.ts inside routes folder
    • call it from index.ts
    1. Serve the data
    • store the data in data/entries.json
    • create src/services/diaryService.ts to manipulate the data
    • configure resolveJsonModule in tsconfig
    1. Create and use types
    • create file src/types.ts
    • add Weather, Visibility types
    • add DiaryEntry interface
    • use our type in diaryService
    • do type assertion for diaryData
    1. Convert the json data directly to typed data
    • create file data/entries.ts and export typed data
    • use typed data directly into service
    1. Defining optional fields in types
    2. Utility types
    • using Pick and Omit to choose or remove from object types
    • create NonSensitiveDiaryEntry from DiaryEntry type by omitting comment field
    • use NonSensitiveDiaryEntry for the service getNonSensitiveEntries
      • there is an issue!
      • modify to manually remove sensitive data
    1. Complete the routes
  • Adding functionalities
    1. Fetching one specific diary entry
    • Add api for specific id
      • fix the problem for potential undefined value
    1. Adding a new diary
    • convert argument to object
    • use utility type to define new diary entry without the id field
    • ignore error in post
    • parse json object in api
    1. Convert the incoming post data to typed data
    • define function toNewDiaryEntry in utils.ts
    • use it in the api
    • remove the ignore error from routes/diaries.ts
    • set the object param to unknown
    1. Check the incoming fields using type guard
    • check comment field
    • check date field
    • weather
      • use Enum
      • also make changes to data/entries.ts
      • need to assert the NewDiaryEntry as DiaryEntry
    • visibility
      • use Enum
    1. Complete the toNewDiaryEntry function
    • we can remove the existence check because of the in operator
    1. Test the new diary entry api

TO-DO:

Part 9-d: React with types

WE-WILL-LEARN:

  • TypeScript will help us catch the following errors:
    • trying to pass an extra/unwanted prop to a component
    • forgetting to pass a required prop to a component
    • passing a prop with the wrong type to a component
  • Useful resources

LECTURE-VIDEO:

  • Create React App with TypeScript
    1. Create my-app with create-react-app using TypeScript template
    • npx create-react-app my-app --template typescript
    1. Modify default app
    • in tsconfig.json, turn off allowJs
    • create .eslintrc
    • add script to run linting
    1. Examining a React component
    • delete all files inside src folder
    • delete all except index.html in public folder
    • create index.tsx in src folder
    • types are defined for component as in a regular function
    • we can remove the return type in component
    • type assertion for document.getElementById
  • Deeper type usage
    1. Create types
    • create file types.ts in src folder
    • add the required interfaces
    • create a union type
    • refactor the types
      • create a base
      • extend the base
    1. Use types in App.tsx
    • create App.tsx
      • import types
      • return null for now
      • export App
    • play around with kind
      • TypeScript implicitly narrows the type based on the kind
    1. Discriminated union - type narrowing of union type based on literal attribute
    • write jsx to show CourseParts
    • show name and exerciseCount
    • use ternary for type narrowing
    1. Exhaustive type checking to make sure all union types have been used
  • React app with state
    1. Create a new App-note.tsx
    • the first useState infers the type string
    • the second useState is not able to infer the type
      • lets explicitly put the type
    1. Add code to initialize some data, and show it in jsx
    2. Add function to create new note
    • put a form with controlled input
    • add onSubmit for the form
      • fix the type error for event
    1. Communicating with the server
    • start the json server from part6/redux-notes
    • install axios
    • get the initial notes from rest api
    • set the generics type for axios.get method
    1. Connect the add note to server
    2. A note about defining object types
    • interface vs type

TO-DO:

Part 9-e: Grande finale: Patientor

WE-WILL-LEARN:

LECTURE-VIDEO:

  • Working with an existing project
    1. Clone and run an existing frontend project
    • https://github.com/fullstack-hy2020/patientor.git
    • cd patientor
    • rm -rf .git
    • npm i
    • npm run dev
    1. Run existing backend project
    • cd patientor-backend
    • npm run dev
    1. Serve the expanded patients data
    • copy the expanded data set
    • create the required types for entry
      • start with a common type, refer to code from Diagnose type for diagnosisCodes
      • extend it
      • creat a union type
      • understanding and using UnionOmit

TO-DO:


Chapters

Part 11-a: Introduction to CI/CD

WE-WILL-LEARN:

  • Software development life cycle
  • Meaning of CI / CD

LECTURE-VIDEO:

  • Software journey from development to production
    1. Follow the GitHub flow for software development
    • create a feature branch
    • complete coding and testing the feature
    • create a Pull request to the main branch
      • another user checks the code, and merges to the main branch
    1. Build the application to make it ready for deploying to server
    2. Deploy the code to production
  • CI / CD
    1. CI: Continuous Integration refers to merging developer changes to the main branch. This involves:
    • merging feature branch to main branch
    • lint
    • build: e.g. build the frontend code and put it in static folder of backend repository
    • test: run all frontend/backend jest, cypress tests to make sure they pass
    • package: e.g. create a zip file of part3/notes-server with ALL required code files including node_modules
    • deploy: e.g. ftp the zip file to production server, unzip it, and restart the node server
    1. CD: could mean Continuous Delivery or Continuous Deployment
    • the practice where the main branch is kept deployable at all times
    • automated deployments triggered from merges into the main branch
    1. Important principals: The goal is better, faster software development with fewer preventable bugs and better team cooperation
    • How to make sure that tests run on all code that will be deployed?
    • How to make sure that the main branch is deployable at all times?
    • How to ensure that builds will be consistent and will always work on the platform it'd be deploying to?
    • How to make sure that the changes don't overwrite each other?
    • How to make deployments happen at the click of a button or automatically when one merges to the main branch?
    1. Types of CI Setup
    • Self hosted setup, e.g. Jenkins
    • Cloud based solution, e.g. GitHub Actions

TO-DO:

Part 11-b: Getting started with GitHub Actions

WE-WILL-LEARN:

  • How to create GitHub Action

LECTURE-VIDEO:

  • Creating a GitHub Action
    1. be aware of the basic needs required to create CI operation
    2. create the folder .github/workflows in the root of the repository
    3. create a workflow file hello.yml inside .github/workflows directory
    4. put the workflow code in YAML with the following elements:
    1. commit & push
    2. check the Actions tab in GiHub to see the workflow
    3. add step to list the files
    • you can configure a GitHub action workflow to start once:
      • An event on GitHub occurs such as when someone pushes a commit to a repository or when an issue or pull request is created
      • A scheduled event, that is specified using the cron-syntax, happens
      • An external event occurs, for example, a command is performed in an external application such as Slack or Discord messaging app
  • Setting up lint, test and build steps
    1. create new workflow file pipeline.yml
    2. add new workflow code
    3. create a job
    • setup environment to run the job
    • add step to checkout the code
    • add step to setup node
    • add step to run npm install (you can set working-directory if required)
    • add step to run linting (you can set working-directory if required)
    1. commit and push code

TO-DO:

Part 11-c: Deployment

WE-WILL-LEARN:

  • deployment

LECTURE-VIDEO:

TO-DO:

Part 11-d: Keeping green

WE-WILL-LEARN:

  • Put conditions for executing Github Actions
  • Versioning git repositories

LECTURE-VIDEO:

  • Workflow in Pull Requests
    1. keep the main branch green
    2. usage of pull requests
    • for code review
    • automate trigger of tasks in the CI pipeline
    1. configure GitHub action to trigger on PR
    • NOTE!! make sure your PR is from your feature branch to YOUR main branch
    1. put condition on deploy step to only execute on certain github.event_name condition
  • About versioning
    1. types of versioning
    • semantic versioning: {major}.{minor}.{patch} (e.g. 1.2.23)
    • hash versioning: is the hash from the commit point
    1. ways to keep track of versions
    • something in the code itself (e.g. a file in the repo with version number)
    • something in the repo or repo metadata (e.g. tags or releases in git)
    • something completely outside the repo (e.g. a spreadsheet that lists the Semantic Version and the commit it points to)
    1. best versioning workflow:
    • CI system keeps track of development by hash versioning
    • once code is successfully merged to main branch, then CI system gives a semantic version
    1. use anothrNick/github-tag-action for automating semantic versioning in GitHub Actions
    • put it in a separate job
    • use the needs keyword to make this job depend on the previous job, simple_deployment_pipeline
    • only run this job on PR merge
    • checkout the code in the first step
    • in the tag step
      • change the default bump to patch
      • add token for authentication in your repository, as the action is third-party which needs authentication
      • only run the step if the commit message does not contain #skip
  • Final notes
    1. when using third party actions, e.g. github-tag-action, it might be a good idea to specify the used version with hash instead of using a version number
    2. keep the main branch protected

TO-DO:

Part 11-e: Expanding Further

WE-WILL-LEARN:

LECTURE-VIDEO:

  • Additional usage of CI pipelines
    1. use commit comments to automate bug tracking systems
    2. automate communications based on CI status
    3. steps to build discord success/failure notification to discord
    1. regarding metrics - keep metrics of build time so that you can
    • project future build times
    • see if there are any sudden build time changes
    1. periodic tasks - automate with either commonly available tools, or, if not available, build automation yourself. you can schedule through GitHub Actions
    2. building vs buying - it's almost always better to use a tool that already does the job than to roll your own solution
    3. creating your own pipeline
    • create a new repo
    • includ phonebook server code into server folder
    • put phonebook frontend into client folder
    • make sure that MONGODB_URI env is entered into heroku config vars
    • make sure HEROKU_API_KEY is entered as github actions secret
    • make sure that the build script in package.json is named build
      • it should build to a folder that is referred from the backend's express.static
    1. protect your main branch
    • require a pull request. make sure approval is required
    • do not allow bypassing even for administrators

TO-DO:


๐Ÿ’š Senior Phase

The senior phase will focus on alrogithms and projects

WEEK 1

Days

Day 1

Grace Shopper

WE-WILL-LEARN:

  • Getting started with e-commerce project

WEB APP DESIGN

  1. requirements, user stories
  • As a <persona>, I want to <do something> so that <reason>
    • example: as a phonebook owner, I want to see all of my contacts, so that I can see their phone number
  1. implementation detail
  • How you will actually fulfill a user story
  • Split each story into specific, bite-size tasks (implementation detail)
    • Should always serve a user story
  • examples:
    • an Express route on the backend (GET /api/contacts) should serve up the name, phone number of all the contacts from our Postgres database. access should be restricted to only the owner of the contact.
    • a React component on the frontend should call /api/contacts on first load, save it on redux, and use contacts from redux to display them on the screen
  1. models
  • list all the different models you will need, e.g. users, contacts
  • write down all the fields for the models
  • draw connections between models, e.g. one-to-one, one-to-many etc
  1. wireframes
  • rough mockups for all the frontend screens

TO-DO:

  • gather user stories
  • models
  • implementation details
  • wireframes
Day 2

WE-WILL-LEARN:

  • Algorithms
    • Linear search
    • Binary search
    • Two crystal ball
    • Bubble sort
  • REACTO
  • Big O
  • System design an ATM Machine

INTERVIEWING USING REACTO

  • Read
    • ask clarifying questions
    • confirm your assumptions with the interviewer
  • Example
    • write down example
      • one simple case
      • edge cases (many, if you can think of)
    • for arrays, always ask
      • is it sorted
      • can there be duplicates
  • Analyze
    • tell your interviewer that you are going to analyze the simpe case first. think aloud to the interviewer as you are analyzing the simple case solution. let her hear all your thoughts; don't just analyze in your mind. come out with the solution that you are able to think of right away, don't try to be clever to come up with the optimal solution in the first go. it is ok if it is a naive solution
    • talk about the Big(O) of the solution
      • time complexity
      • space complexity
  • Code it completely
  • Test it using the simple example
    • then test for some of the edge cases, and see if you need to modify code for it
  • Optimize solution if possible. but since you have done naive solution already, there isn't pressure to complete it

BIG O NOTATION

Big O is a way to categorize your algorithm's time or memory requirements based on input. It is not meant to be an exact measurement. It will not tell you how many CPU cycles it takes, instead it is meant to generalize the growth of your algorithm.

  • Big O of time
    • O(N) - if there is one loop through the input
    • O(N^2) - if there is nested loop through the input
    • O(log N) - if the input is halved in each step
    • O(N log N) - if the input is halved in each step
  • Big O of space
    • how much memory is the algorithm going to consume?
    • generally, not much focus will be put on this
    • it only comes into focus when using hashing function

While calculating Big O

  1. look for loops!
  2. growth is with respect to the input
  3. constants are dropped
  4. worst case is usually the way we measure

TO-DO:

  • REACTO interview problems
  • Web app design for Blogslist

TEMPLATE
Part :

WE-WILL-LEARN:

LECTURE-VIDEO:

  • 1.

TO-DO:

About

This is full Stack modern web Dev course.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages