Coder Social home page Coder Social logo

nf-backend-fishproducts's Introduction

Backend Read: Products

In this challenge (and the upcoming ones), you'll create a fish shop. For now, you'll read data from a local MongoDB using mongoose and display it in the frontend.

Task

Introduction

Run npm run dev and open localhost:3000 on your browser.

Have a look around:

  • there is an overview page with all products and a details page for each of them;
  • the data is taken from lib/products.js.

Your task is to refactor the app so that it fetches the data from a local MongoDB.

Read Products from Database

Use MongoDB Compass to create a database:

  • the database should be called fish-shop,
  • there should be one collection called products,
  • download and extract the resources and
  • use the products.json file to import the data into your products collection.

Create a schema for the Product model in the db/models folder.

The schema should have the following fields:

  • name (String)
  • description (String)
  • price (Number)
  • currency (String)

At the root of the project, create a .env.local file which uses the MONGODB_URI environment variable and your MongoDB connection string.

  • Copy and paste the following into the .env.local file: MONGODB_URI=mongodb://localhost:27017/fish-shop.

Switch to pages/api/products/index.js:

  • Delete the import of lib/products.

  • Import dbConnect from the db/connect.js file.

  • Import the Product model.

  • Make the handler function async and await the connection to the database.

  • If the request.method is GET,

    • use the Product model to find all products and
    • return them as a response.

Switch to pages/index.js and adapt the frontend:

  • replace all instances of product.id with product._id.

Check that it works:

  • Reload localhost:3000; you should still see all fishes.

Switch to pages/api/products/[id].js and adapt it as explained above:

  • To find a single product by its id, you can use the Product model and the .findById() method: Product.findById(id).
  • Delete lib/products.js because it is not used anymore.

Open the browser and check the details pages: they should now work as well!

Bonus: Populate Reviews

Some of the products already have reviews which are stored in a second collection. Your task is to read from that collection and display the reviews on the right details page.

Open MongoDB Compass and adapt your fish-shop database:

  • Add a new collection called reviews; insert the data from bonus-reviews.json.
  • Drop the products collection; recreate it with the same name, but now insert data from the bonus-products.json file.
    • Note: The data in bonus-products.json contain a reviews array with ids as a reference to the corresponding review in the review collection.

Create a schema for the Review model in the db/models folder.

The schema should have the following fields:

  • title (String)
  • text (String)
  • rating (Number)

Update the Product schema to include a reference to the Review model:

  • Import the Review model with import "./Review";
  • Below the currency key, add a new line for the reviews; you want to define that it is an array of Object-Ids and has a reference to the Review schema like so: reviews: { type: [Schema.Types.ObjectId], ref: "Review" },

Switch to pages/api/products/[id].js and use the .populate method to integrate the reviews for each product:

  • const product = await Product.findById(id).populate("reviews");

Finally, update the frontend to display the reviews:

  • Switch to components/Product/index.js.
  • Inside of the return statement, check whether the fetched data contain any reviews and if so, display them.
  • Feel free to decide which part of the review data you want to display.

Resources

โฌ‡๏ธ You can download the data and assets for the Fish Shop here.

  • Unzip the file to get the resources folder.
  • The files are already in the correct structure for the app.
    • products.json contains the data for the first task, and
    • bonus-products.json and bonus-reviews.json contain the data for the bonus task.
  • Import them into the correct collection of your local MongoDB when you are asked to.

Backend Create: Products

In this challenge, you'll further expand a fish shop. This time, you'll create new data in your local MongoDB using mongoose and refresh the UI programmatically to display the new product immediately.

๐Ÿ’ก You can use this template as a starting point. But if you are far enough along with your own Fish Shop App, please use that instead.

Task

Prepare your Database

If you have not done so, use MongoDB Compass to create a database:

  • the database should be called fish-shop,
  • there should be two collections: products and reviews,
  • download and extract the resources and
  • import the data of the products.json file into your products collection;
  • import the data of the reviews.json file into your reviews collection.

Create a .env.local file based on the .env.local.example. Be sure to spell the name of the database (fish-shop) correctly.

Introduction

Run npm run dev and open localhost:3000 in your browser.

Have a look around:

  • there is an overview page with a form to add a new fish and a list of all products below that form;
  • when clicking a product in the list, you'll be redirected to a details page;
  • note that submitting the form does not do anything right now.

Your task is to refactor the app so that submitting the form creates a new entry in your local MongoDB and refreshes the page to show all products (including the new one).

Add a POST route

Switch to pages/api/products/index.js and write the code for the request.method POST :

  • Use a try...catch block.
  • Try to:
    • Save the product data submitted by the form - accessible in request.body - to a variable called productData.
    • use Product.create with the productData to create a new document in our collection.
    • Wait until the new product was saved.
    • Respond with a status 201 and the message { status: "Product created." }.
  • If an error occurs:
    • Log the error to the console.
    • Respond with a status 400 and the message { error: error.message }.

Submitting the form will not yet work because the form does not know that you've created a POST route it can use.

Send a POST request

Switch to components/ProductForm/index.js:

  • There already is a handleSubmit function which creates a productData object with all relevant data.

Your task is to fetch your new POST route and send the data to your database. After that use mutate from useSWR to refetch the data from the database.

  • call useSWR in your JokeForm component with the API endpoint and destructure the mutate method.
  • inside the handleSubmit function:

    ๐Ÿ’ก Hint: have a look at the handout if you get stuck here.

  • send a "POST" request with fetch using the following options as the second argument
{
  method: "POST",
headers: {
  "Content-Type": "application/json",
  },
body: JSON.stringify(???),
}
  • use the jokeData from the form input as the body of the request
  • await the response of the fetch, if the fetch was successful, call the mutate method to trigger a data revalidation of the useSWR hooks

Open localhost:3000/ in your browser, submit a new fish and be happy about your shop being expanded!

Resources

โฌ‡๏ธ You can download the data and assets for the Fish Shop here.

  • Unzip the file to get the resources folder.
  • The files are already in the correct structure for the app.
    • products.json contains the data for the all fish,
    • reviews.json contain the data for all reviews.
  • Import them into the correct collection of your local MongoDB when you are asked to.

Backend Update and Delete: Products

In this challenge, you'll further expand a fish shop. This time, you'll update and delete data in your local MongoDB using mongoose.

๐Ÿ’ก You can use this template as a starting point. But if you are far enough along with your own Fish Shop App, please use that instead.

Task

Prepare your Database

If you have not done so, use MongoDB Compass to create a database:

  • the database should be called fish-shop,
  • there should be two collections: products and reviews,
  • download and extract the resources and
  • import the data of the products.json file into your products collection;
  • import the data of the reviews.json file into your reviews collection.

Create a .env.local file based on the .env.local.example. Be sure to spell the name of the database (fish-shop) correctly.

Introduction

Run npm run dev and open localhost:3000 in your browser.

Have a look around:

  • there is an overview page with a form to add a new fish and a list of all products below that form;
  • when clicking a product in the list, you'll be redirected to a details page.

Your task is to add the functionality for updating and deleting a product. The buttons to do so should be visible on the Product Details Page and after sending the request, the user is redirected to the Overview Page.

PUT Request

Add a PUT route

Switch to pages/api/products/[id].js and write the code for the request.method PUT :

  • Wait for Product.findByIdAndUpdate(id, { $set: request.body, }).
  • Respond with a status 200 and the message { status: "Product successfully updated." }.

Refactor the ProductForm component

For now, the ProductForm component sends a POST request to your database. We want to reuse the component for editing products and sending PUT requests as well.

Switch to components/ProductForm/index.js.

Lift up all logic regarding the creating of the productData to the pages/index.js file.

๐Ÿ’ก This includes the destructuring of const { mutate } = useSWR("/api/products");, the handleSubmit function and the import of useSWR.

After doing so,

  • rename the handleSubmit function to handleAddProduct
  • in the return statement, pass handleAddProduct to the ProductForm component as a prop called onSubmit.

Switch back to components/ProductForm/index.js and

  • receive the onSubmit prop.
  • use onSubmit instead of handleSubmit in the form

๐Ÿ’ก Bonus: Pass another new prop to the ProductForm component to set the heading of the form dynamically ("Add a new Fish" is not a proper headline when updating the product, right?).

Send a PUT request

Switch to components/Product/index.js.js.

You will need the mutate method to revalidate the product data after a successful update:

  • destructure mutate from the object received from the useSWR hook.

Below this code, create a handleEditProduct() function:

  • it receives event as parameter,
  • it stores the submitted data in a variable called productData (Hint: new FormData and Object.fromEntries as already used)
  • it starts a "PUT" request with fetch (hint: this fetch is similar to the "POST" fetch we perform to create products)
  • uses mutate after a successful fetch to update the product detail page.

We need to update the content of our Product component to display the edit form:

  • Create a state called isEditMode and initialize it with false.
  • In the return statement, add a <button> with
    • type="button",
    • onClick={() => { setIsEditMode(!isEditMode); }},
    • and a proper text.
  • In the return statement, display the ProductForm component depending on the isEditMode state (Hint: isEditMode && ...).
  • pass our handleEditProduct function to the ProductForm as the onSubmit prop.

Open localhost:3000/ in your browser, switch to a details page, edit a fish and be happy about your shop being expanded!

DELETE Request

Add a DELETE route

Switch to pages/api/products/[id].js and write the code for the request.method DELETE :

  • Wait for Product.findByIdAndDelete(id).
  • Respond with a status 200 and the message { status: "Product successfully deleted." }.

Send a DELETE request

Deleting a product should be possible from the details page.

Switch to components/Product/index.js and implement a delete button:

  • In the return statement, add a <button> with
    • type="button",
    • onClick={() => handleDeleteProduct(id)},
    • and a proper text.

Write the handleDeleteProduct function:

  • Wait for a fetch() with two arguments:
    • the url /api/products/${id} and
    • an options object { method: "DELETE" }
  • Save the result in a variable called response.
  • If the response is ok,
    • wait for response.json() and use push("/").
  • If the response is not ok, log the response.status as an error to the console.

Open localhost:3000/ in your browser, switch to a details page, delete a fish and be happy about your shop being expanded!

Resources

โฌ‡๏ธ You can download the data and assets for the Fish Shop here.

  • Unzip the file to get the resources folder.
  • The files are already in the correct structure for the app.
    • products.json contains the data for the all fish,
    • reviews.json contains the data for all reviews.
  • Import them into the correct collection of your local MongoDB when you are asked to.

Development

CodeSandbox

Select the "Browser" tab to view this project. If this project contains tests, select the "Tests" tab to check your progress.

Local development

To run project commands locally, you need to install the dependencies using npm i first.

You can then use the following commands:

  • npm run dev to start the development server
  • npm run build to create a production build
  • npm run start to start the production build
  • npm run test to run the tests in watch mode (if available)

๐Ÿ’ก This project requires a bundler. You can use npm run dev to start the development server. You can then view the project in the browser at http://localhost:3000. The Live Preview Extension for Visual Studio Code will not work for this project.

nf-backend-fishproducts's People

Stargazers

Veliko avatar

Watchers

Veliko avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.