Undefined errors in node.js

I would like to seek help on undefined errors which I been trying to solve but no luck for 2 weeks already. I'm trying to create a button with On/Off function. If the users click On button, it will light up my LED and also store to mySQL database of what time that users click on it. Hope you guys could help me out with it as soon as possible, thanks in advance, guys.

This is my app.js:

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var pin = require('./routes/pin');
var app = express();

// View engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.set('port', process.env.PORT || 3000);

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('', index);
app.use('/pin', pin);

// Catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});

module.exports = app;
var server = app.listen(app.get('port'), function() {
  console.log('Listening on port %d', server.address().port);
});

This is my index.js:

var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var gpio = require('pi-gpio');

var conn = {
    host: 'localhost',
    user: 'user',
    password: 'password',
    database: 'rest_api',
    port: '3306'
};

router.get('/', function(req, res) {
    var pin = req.params.pin;
    var connection = mysql.createConnection(conn);
    var querySensorInfo ='SELECT sensorId, sensor, pinNo, sensorType FROM sensorInfo';

    connection.query(querySensorInfo, function(err, rows, fields) {
            if (err) {
            throw err;
        }
        console.log(rows);
            res.render('index', { 
            title: 'Sensor Rest API', 
            sensorInfoData: rows
        });    
    });

    var pin7On = gpio.open(7, 'output', function(err) {
            if ('output' == 1) {
                gpio.write(7, 1, function(err) {
                    connection.query('INSERT INTO sensorLog(sensorId, logTime, sensorValue) VALUES(1, current_timestamp(), 1)', function(err) {
                        if (err) {
                            throw err;
                            } else {
                            console.log("Successfully store to mySQL database");
                        }
                    });
                        gpio.close(7);
                });
            }
    });

    var pin7Off = gpio.open(7, 'output', function(err) {
            if ('output' == 0) {
                gpio.write(7, 0, function(err) {
                    connection.query('INSERT INTO sensorLog(sensorId, logTime, sensorValue) VALUES(1, current_timestamp(), 1)', function(err) {
                        if (err) {
                            throw err;
                            } else {
                            console.log("Successfully store to mySQL database");
                        }
                    });
                        gpio.close(7);
                });
            }
    });

});

module.exports = router;

This is my /view/index.ejs:

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1 align="center">
    <%= title %>
    </h1>
    <p align="center">
    This are the <b>Sensors Information Log</b>, which shows what sensor are available to activate.
    </p>
    <table border="1" cellpadding="2" cellspacing="2" align="center">
    <tr>
         <th>Sensor ID</th>
         <th>Sensor</th>
         <th>Pin Number</th>
         <th>Sensor Type</th>
    </tr>
    <% for(var i = 0; i < sensorInfoData.length; i++) { %>
        <tr align="center">
             <td><%= sensorInfoData[i].sensorId%></td>
             <td><%= sensorInfoData[i].sensor%></td>
             <td><%= sensorInfoData[i].pinNo%></td>
             <td><%= sensorInfoData[i].sensorType%></td>
        </tr>
    <% } %>
    </table>
    <button value=1 onClick=<%= pin7On%>>ON</button> 
    <button value=0 onClick=<%= pin7Off%>>>OFF</button>
  </body>
</html>

This is error message:

/var/www/views/index.ejs:30 28| <% } %> 29| </table> >> 30| <button value=1 onClick=<%= pin7On%>>ON</button> 31| <button value=0 onClick=<%= pin7Off%>>>OFF</button> 32| </body> 33| </html> pin7On is not defined

undefined

ReferenceError: /var/www/views/index.ejs:30
    28|     <% } %>
    29|     </table>
 >> 30|     <button value=1 onClick=<%= pin7On%>>ON</button> 
    31|     <button value=0 onClick=<%= pin7Off%>>>OFF</button>
    32|   </body>
    33| </html>

pin7On is not defined
    at eval (eval at <anonymous> (/var/www/node_modules/ejs/lib/ejs.js:237:14), <anonymous>:29:1141)
    at eval (eval at <anonymous> (/var/www/node_modules/ejs/lib/ejs.js:237:14), <anonymous>:29:1277)
    at /var/www/node_modules/ejs/lib/ejs.js:250:15
    at Object.exports.render (/var/www/node_modules/ejs/lib/ejs.js:288:13)
    at View.exports.renderFile [as engine] (/var/www/node_modules/ejs/lib/ejs.js:318:20)
    at View.render (/var/www/node_modules/express/lib/view.js:76:8)
    at Function.app.render (/var/www/node_modules/express/lib/application.js:503:10)
    at ServerResponse.res.render (/var/www/node_modules/express/lib/response.js:802:7)
    at Query._callback (/var/www/routes/index.js:24:11)
    at Query.Sequence.end (/var/www/node_modules/mysql/lib/protocol/sequences/Sequence.js:96:24)

Well first off, @brenden-scarvell is right in saying the error stems from the fact that you are not passing in those variables when you render the template.

res.render('index', {
    title: 'title',
    sensorInfoData: data,
    pin7On: pin7On,
    pin7Off: pin7Off
}):

The bigger issue, is that what you are trying to do is impossible using your current methods. When a template is rendered and sent to a browser, it no longer has any connection to your node instance. That means you can't save stuff to the database or do any server side code directly from the onClick listener. Instead you will need to use ajax requests to communicate between the browser and server.

First you'll want to modify the router to add some more points of communication. Something like:

router.post('/pin7Off', function() {
    // database stuff in here
    // send success response when done
});

router.post('/pin7On', function() {
    // database stuff in here
    // send success response when done
});

Now in your template. Add code that sends an AJAX request to the server when the button is clicked. Here's roughly how you would do it in jQuery.

$("#buttonOne").on('click', function() {
    $.ajax({
        url: '/pin7On',
        method: 'POST'
    });
});

Remember, the above code will be in the ejs template you send to the browser.