#Express + EJS dynamic route error - cannot read undefined - but reading it...

59 messages · Page 1 of 1 (latest)

real turtle
#
app.get('/monsters/:slug', function(request, response) {
  const monster = monsterData.find( function(monster) {
    return monster.slug == request.params.slug;
  });
  response.render('detail', { monster });
});

.

<%- include('header.ejs') %>

<section>
  <inner-column>

    <%=monster.portrait%>

Shows up fine in the HTML output and in the browser
.

But I get this error in the console

Server started at http://localhost:1982
TypeError: /Users/sheriffderek/Desktop/express-monsters/views/detail.ejs:7
    5|     <inner-column>
    6|
 >> 7|       <%=monster.portrait%>
    8|
    9|       <monster-detail>
    10|     <picture class='portrait'> ...

Cannot read properties of undefined (reading 'portrait')
    at eval ("/Users/sheriffderek/Desktop/express-monsters/views/detail.ejs":13:33)
    at detail (/Users/sheriffderek/Desktop/express-monsters/node_modules/ejs/lib/ejs.js:703:17)
    at tryHandleCache (/Users/sheriffderek/Desktop/express-monsters/node_modules/ejs/lib/ejs.js:274:36)
    at exports.renderFile [as engine] (/Users/sheriffderek/Desktop/express-monsters/node_modules/ejs/lib/ejs.js:491:10)
    at View.render (/Users/sheriffderek/Desktop/express-monsters/node_modules/express/lib/view.js:135:8)
    at tryRender (/Users/sheriffderek/Desktop/express-monsters/node_modules/express/lib/application.js:657:10)
    at Function.render (/Users/sheriffderek/Desktop/express-monsters/node_modules/express/lib/application.js:609:3)
    at ServerResponse.render (/Users/sheriffderek/Desktop/express-monsters/node_modules/express/lib/response.js:1039:7)
    at file:///Users/sheriffderek/Desktop/express-monsters/index.js:33:11
    at Layer.handle [as handle_request] (/Users/sheriffderek/Desktop/express-monsters/node_modules/express/lib/router/layer.js:95:5)

Any ideas why this might be happening?

trail abyss
#

Is monster variable (which value is returned from monsterData.find()) is other than undefined?

real turtle
#

I don't have a condition in place to handle a missing monster.

#
[
    {
        "id": 0,
        "slug": "bunchy",
        "name": "Bunchy",
        "adopted": false,
        "color": "green",
        "portrait": "bunchy.png"
    },
    {

JSON looks like this

#

url: /monsters/bunchy (being the :slug) -

#

Looks like it's happening twice.

#

Why would this run twice?

#

.

#

.

#
import express from 'express';
import monsterData from './monsters.json' assert { type: 'json' };

const app = express();

app.set('view engine', 'ejs');


app.get('/monsters/:slug', function(request, response) {

    const monster = monsterData.find( function(monster) {
        console.log(monster.slug, request.params.slug);
        return monster.slug == request.params.slug;
    });

    console.log('x', monster);

    response.render('detail', { monster });
});


app.listen(1982, function() {
    console.log("Server started at http://localhost:1982");
});

Simplified down ^

#
bunchy bunchy
x {
  id: 0,
  slug: 'bunchy',
  name: 'Bunchy',
  adopted: false,
  color: 'green',
  portrait: 'bunchy.png'
}
bunchy favicon.svg
munchy favicon.svg
crunchy favicon.svg
x undefined
TypeError: ...

I don't understand why these other resources are on the request.params object.

trail abyss
real turtle
#

In my case, I'm just refreshing the browser window locally.

#

1 time.

#

1 refresh gets this

#

Just using command + R

#

Same thing with the refresh button and a mouse.

#

(Trying in other browsers)

#

Firefox -- just shows the 1

#

And no error ---

#

Same with Safari

#

So.... maybe it's a Chrome extension - or Sublime browser-refresh package or something -

#

Tested with Chrome Canary (which is stock/no extensions) - and it also gives the error.

#

.

#

.

#

I added a favicon - and now it doesn't make 2 requests.

#

What a whacky situation!!!!

#

Well, thanks for hearing me out.

trail abyss
real turtle
#

I thought about it some more...

#

It's not only - just not having the favicon ---

#

I had this in there as a default <link rel='icon' type='image/svg+xml' href='favicon.svg'>

#

and so I think - along the lines of what you're saying ---- it's really the missing /

#

href='whatever.ext - is going to be looking for the relative path on /monsters then?

#

so - href='/favicon.ico' - solves for that.

#

(So - in the end... it's not Chrome -- it's just ME -- not adding the / - and then the route thinking it's loading something at that monsters/favicon.svg path !!!

#

Thank you for making sure I looked into it further.

trail abyss
real turtle
#

There's no base set.

#

monsters/:slug - would load the monsters view

#

and there's a header partial

#

and in that - the favicon href='favicon.svg'

#

Which is trying to then load monsters/favicon.svg - and when you console.log( request.params ) ....

#

I got both:

#
{ 
  slug: "monster-name"
}

and

{ 
  slug: "favicon.svg"
}
trail abyss
#

So i guess you should have more specific path in url

#

What's the full URL?

real turtle
#

Well, it was reading this URL
localhost:1982/monsters/favicon.svg
when I was requesting the
localhost:1982/monsters/monster-slug url -- because I didn't have the / before the favicon link.

#

The same thing would happen with localhost:1982/monsters/monster-slug/style.css
if you didn't have a preceding forward-slash on the css link.

trail abyss
real turtle
#

Yep!