0

I have been following a tutorial on setting up REST APIs in Node, using Express for an app that accesses an existing MariaDB database. My version only needs to read data and I have the DB co-located with the Node application (same host).

My goal for this entry-level example is to just access the data, using static SQL, so I can see it rendered in the web page by the JSON pritifier.

[Next, I want to present the data in a table (EJS?). Later, when I can get that to work, I'll add form controls (React?) to let a user specify start and end date bounds for the SQL query. Finally I'll aim to render the data as a line graph (D3js).]

The tutorial runs the web server successfully (it returns 'OK' on the base URL), but when I go to URL/solarData it tries an async function to getMultiple rows from the DB, it responds solarData.getMultiple is not a function TypeError: solarData.getMultiple is not a function

./app.js

const express = require('express');
const app = express();
const port = process.env.PORT || 3800;
const solarDataRouter = require('./routes/solarData');

app.use(express.json());
app.use(
  express.urlencoded({
    extended: true,
  })
);

app.get('/', (req, res) => {
  res.json({'message': 'ok'});
})

app.use('/solarData', solarDataRouter);

/* Error handler middleware */
app.use((err, req, res, next) => {
  const statusCode = err.statusCode || 500;
  console.error(err.message, err.stack);
  res.status(statusCode).json({'message': err.message});


  return;
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
});

./routes/solarData.js

const express = require('express');
const router = express.Router();
const solarData = require('../services/solarData');

/* GET solar data. */
router.get('/', async function(req, res, next) {
  try {
    res.json(await solarData.getMultiple(req.query.page));
  } catch (err) {
    console.error(`Error while getting solar data `, err.message);
    next(err);
  }
});
module.exports = router;

./config.js

const env = process.env;

const config = {
  db: { 
    host: env.SUNNY_HOST,
    user: env.SUNNY_USER,
    password: env.SUNNY_PW,
    database: env.SUNNY_DB,
  },
  listPerPage: env.LIST_PER_PAGE,
};

module.exports = config;

./services/solarData.js

const db = require('./db');
const helper = require('../helper');
const config = require('../config');

async function getMultiple(page = 1){
  const offset = helper.getOffset(page, config.listPerPage);
  const rows = await db.query(
    `SELECT idxDTP, year(DT) AS Year, month(DT) AS Month, day(DT) AS Day, hour(DT) AS Hour, minute(DT) AS Min, PWR AS Power FROM DTP WHERE (DT >= '2021-01-12 12:30:00') AND (DT <= '2021-01-12 12:40:00') ORDER BY Year ASC, Month ASC, Day ASC, Hour ASC, Min ASC LIMIT ?,?`, 
    [offset, config.listPerPage]
  );
  const data = helper.emptyOrRows(rows);
  const meta = {page};

  return {
    data,
    meta
  }
}

./services/db.js

const mysql = require('mysql2/promise');
const config = require('../config');

async function query(sql, params) {
  const connection = await mysql.createConnection(config.db);
  const [results, ] = await connection.execute(sql, params);

  return results;
}

module.exports = {
  query
}

I've left out the ./helper.js

Everything runs fine until I direct the webpage to /solarData. At that point I get: Debug Console (vscode)

/Error while getting solar data  solarData.getMultiple is not a function
routes/solarData.js:10
solarData.getMultiple is not a function TypeError: solarData.getMultiple is not a function
    at /SunnyData/solarViz/routes/solarData.js:8:30
    at Layer.handle [as handle_request] (/SunnyData/solarViz/node_modules/express/lib/router/layer.js:95:5)
    at next (/SunnyData/solarViz/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/SunnyData/solarViz/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/SunnyData/solarViz/node_modules/express/lib/router/layer.js:95:5)
    at /SunnyData/solarViz/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/SunnyData/solarViz/node_modules/express/lib/router/index.js:335:12)
    at next (/SunnyData/solarViz/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/SunnyData/solarViz/node_modules/express/lib/router/index.js:174:3)
    at router (/SunnyData/solarViz/node_modules/express/lib/router/index.js:47:12)

No doubt it's a simple problem but I can't find existing questions that cover this scenario in a way I can understand (I'm new to Node/Express, etc)

Hope I've put enough info in. Please ask if I need to add anything else.

1
  • You are missing the export line module.exports = getMultiple; in the solarData service. Commented Aug 30, 2021 at 9:57

1 Answer 1

2

You should add at the end of ./services/solarData.js the following line to export the function;

module.exports.getMultiple = getMultiple;

It will allow Node.js to export the function and require it in other files

Sign up to request clarification or add additional context in comments.

1 Comment

Fixed it in One. Thank you :) (though it's now reporting "Bind parameters must not contain undefined. To pass SQL NULL specify JS null", but that's a whole new post ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.