Search code examples
javascriptreactjsexpressaxiosreact-dom-server

React Express TypeError: Cannot read property 'then' of undefined


I'm trying to render my react app on server incase the user has disabled javascript and also for better search result. But somewhere between export and using the function, I got the TypeError: Cannot read property 'then' of undefined error.

Here are some of my code

// serverRender.js
import ReactDOMServer from 'react-dom/server';
import axios from 'axios';

const serverRender = () => {
    axios.get(`${config.serverUrl}/api/content`)
        .then(res => {
            return ReactDOMServer.renderToString(
                <App initialData={res.data.content} />
            );
        })
        .catch(console.error);
}

export default serverRender;

I then inject the code in my server.js

// server.js
import express from 'express';    
import serverRender from './serverRender';

const server = express();
server.get('/', (req, res) => {
    serverRender()
        .then(content => {
            res.render('index', {
                content
            });
        })
        .catch(console.error);
});

I also tried just

// serverRender.js
axios.get(`${config.serverUrl}/api/content`)
    .then(res => {
        console.log(
            ReactDOMServer.renderToString(
                <App initialData={res.data.content} />
            )
        );
    })
    .catch(console.error);

And I did see the rendered content on my console. Please let me know what's wrong, thanks!

p.s. full error here

TypeError: Cannot read property 'then' of undefined
    at /.../server.js:19:5
    at Layer.handle [as handle_request] (/.../node_modules/express/lib/router/layer.js:95:5)
    at next (/.../node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/.../node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/.../node_modules/express/lib/router/layer.js:95:5)
    at /.../node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/...t/node_modules/express/lib/router/index.js:335:12)
    at next (/.../node_modules/express/lib/router/index.js:275:10)
    at sass (/.../node_modules/node-sass-middleware/middleware.js:127:14)
    at Layer.handle [as handle_request] (/.../node_modules/express/lib/router/layer.js:95:5)

Solution

  • You need to return a promise from your serverRender function if you want it to be 'thenable'. At the moment, you're not returning anything from that function.

    // serverRender.js
    const serverRender = () => {
    return axios.get(`${config.serverUrl}/api/content`)
        .then(res => {
            return ReactDOMServer.renderToString(
                <App initialData={res.data.content} />
            );
        })
        .catch(console.error);
    }
    
    export default serverRender;