Search code examples
expressejs

ERROR: TypeError: Cannot read properties of undefined (reading 'username')


This is my whole code. I am trying to locate on my page.ejs page through /insta/:id but it is showing the error:

Cannot read properties of undefined (reading 'username').

I want to get id that uuidv4() will be giving but instead it is returning username. And also I want to get the specific post through the id(which is getting username value and not the generated id) but my post variable didn't get any specific post in it.

This is index.js

const express=require("express");
const app=express();
const path=require("path");
const { v4: uuidv4 } = require('uuid');
const port=3000;

let posts=[
    {   
        username:"evablue@2",
        image:"/post1.jpg",
        content:"Enjoying at this beautiful beach :)",
        tags:"",
        id:uuidv4(),
    },
    {
        username:"purple_whale",
        image:"/post2.jpg",
        content:"A pic should be clicked before digging in <**>",
        tags:"@shresDrawMystry, @riddhiMolala",
        id:uuidv4(),
    },
    {
        username:"nature'sBaby",
        image:"/post3.avif",
        content:"Love clicking beautiful moments.",
        tags:"@bankpyt",
        id:uuidv4(),
    },
    {
        username:"butterscoth#Love",
        image:"/post4.jpg",
        content:"It's Holi.Woooooohoooo.",
        tags:"",
        id:uuidv4(),
    },
    {
        username:"coffeeLover",
        image:"/post5.jpg",
        content:"Explored a new Cafe.",
        tags:"@RelaxCafe",
        id:uuidv4(),
    }
]

app.use(express.urlencoded({ extended:true }))
app.use(express.json());
app.use(express.static("public"));

app.set("view engine","ejs");
app.set("views",path.join(__dirname,"/views"));

app.get("/insta",(req,res)=>{
    res.render("home.ejs",{ posts });
})
app.get("/insta/:id",(req,res)=>{     
    let {id}=req.params;
    let post=posts.find((p)=> id===p.id );
    console.log(req.params);
    res.render("page.ejs",{ post });
})


app.listen(port,()=>{
    console.log("Port 3000 is listening requests");
})

This is page.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?        family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
    <title><%= post.username %></title>
</head>
<body>
    <div class="header">
        <div class="dp">
            <img src="<%= post.image %>">
        </div>
        <div class="info">
            <h5><%= post.username %></h5>
            <button>Follow</button>
            <button>Message</button>
             <button><span class="material-symbols-outlined">person_add</span></button>
        </div>
    </div>
</body>
</html>

Solution

  • You are getting the error: Cannot read properties of undefined (reading 'username') from your page.ejs file when you try to access username here:

    <title><%= post.username %></title>
    

    The post object is empty because of the way you are using the uuid library.

    When you create your posts array, the uuidv4() function generates a new value every time your server restarts:

    let posts=[
        {   
            username:"evablue@2",
            image:"/post1.jpg",
            content:"Enjoying at this beautiful beach :)",
            tags:"",
            id:uuidv4(), // id:2d98e533-769e-4352-83ea-c4fdbc516d73
        },
        {
            username:"purple_whale",
            image:"/post2.jpg",
            content:"A pic should be clicked before digging in <**>",
            tags:"@shresDrawMystry, @riddhiMolala",
            id:uuidv4(), // id:6064012d-cf4f-4445-88c8-e62d25153c98
        },
        ...
    ];
    

    How do you know which value to pass to your app.get("/insta/:id" route?

    Your router looks fine but you would need to add console.log('posts:', posts) straight after you create the array so you can actually see what value the uuidv4() has added for each id within the posts array. You could then navigate to:

    'http://localhaost:3000/insta/6064012d-cf4f-4445-88c8-e62d25153c98'
                                //^^ Replace this with one of the values shown in the console.log('posts:', posts)
    

    However, this is very cumbersome and you should just use a database like MySQL or MongoDB. I appreciate that will be another technical challenge but you won't be able to rely on an array forever. Read the docs and have faith in yourself!