0

I'm running a simple program with the server side on Node with cheerio. Given below are the codes:

Server Side:

/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path')
  , request = require ('request')
  , cheerio = require ('cheerio')
  , $;
 

var app = express();
//console.log($('[class = "orange"]').attr('id'));
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.get('/', routes.index);
app.get('/users', user.list);
request('http://localhost:3000', function (error, response, html) {
    if (!error && response.statusCode == 200) {
        $ = cheerio.load(html);
    }   
});
app.listen(3000);
var temp2=9;
app.get('/data2', function(req, res){
    
    //var $ = cheerio.load('<body>');
    //var temp = $('[class="orange"]').attr('id');
    console.log(temp2);
      res.send(temp2); //replace with your data here
});
app.get('/data', function(req, res){
    //var $ = cheerio.load('<body>');
    var temp = $('[class="orange"]').attr('id');
    console.log(temp);
      res.send(temp); //replace with your data here
});

index.ejs (Express Template)

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js" type="text/javascript"></script>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>

  <body>
    <h1><%= title %></h1>
      <input type="button" id="stopButton" value="Button1"/>
      <input type="button" id="stopButton2" value="Button2"/>
    <p>Welcome to <%= title %></p>
  <ul id="fruits">
  <li id= "1" class="apple">Apple</li>
  <li id = "2" class="orange">Orange</li>
  <li id = "3" class="pear">Pear</li>
</ul>
  <script type="text/javascript">
      $(document).ready(function () {
          $('#stopButton').click(function () {
              $.get('http://localhost:3000/data', {}, function (data) {
                  $('[id="2"]').html(data);
              });
          });
          $('#stopButton2').click(function () {
              $.get('http://localhost:3000/data2', {}, function (data2) {
                  console.log(data2);
                  $('[id="2"]').text(data2);
              });
          });
      });
 </script> 
 </body>
</html>

The template creates a list of items and displays it on the HTML.

  1. Apple
  2. Orange
  3. Pear

Also displayed on the HTML are 2 buttons: Button1 and Button2.

When I press Button1, 'Orange' changes to number 2. When I press Button2, ideally Orange should change to number 9, but it doesn't. Is there something wrong?

The console.log() for both buttons work perfectly well numbers 2 and 9 shown in the console.

Any help would be appreciated.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
NeelDeveloper
  • 139
  • 1
  • 15

1 Answers1

0

There are some misunderstandings here. This code

request('http://localhost:3000', function (error, response, html) {
    if (!error && response.statusCode == 200) {
        $ = cheerio.load(html);
    }   
});
app.listen(3000);

doesn't make sense--you're making a request to your own server in order to create the $ object to use Cheerio to parse the form. Then, when a request comes through, you try to pull the user's form data from that HTML that you parsed long ago when the server started using var temp = $('[class="orange"]').attr('id');.

Cheerio isn't able to dynamically track all of the served HTML form values on various clients, so it'll never have any of the dynamic data you may expect it to have, just the same raw HTML you're serving to the client.

Cheerio isn't useful here at all as far as I can tell. It's primarily a web scraping tool for extracting data from other websites' HTML. Data submitted by your clients to the server is taken from the payload, parameters and query string of an HTTP request using request.body, request.params and request.query. POST body payloads are commonly JSON or URL-encoded form data.

Here's a simple example of how you can send data to the server using a GET request's query string and respond with a value that the client can insert into the document. You can adapt this to your use case.

views/index.ejs:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title><%= title %></title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
  </head>
  <body>
    <h1><%= title %></h1>
    <input type="button" id="stop-button" value="Button1" />
    <p>Welcome to <%= title %></p>
    <ul id="fruits">
      <li id="1" class="apple">Apple</li>
      <li id="2" class="orange">Orange</li>
      <li id="3" class="pear">Pear</li>
    </ul>
    <script>
      $(document).ready(() => {
        $("#stop-button").click(() => {
          const url = "http://localhost:3000/data";
          const word = $("#1").text();
          $.get(url, {word}, ({data}) => $("#2").html(data));
        });
      });
    </script>
  </body>
</html>

server.js:

const express = require("express");
const path = require("path");

const app = express();
app.set("port", process.env.PORT || 3000);
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use(express.static(path.join(__dirname, "public")));

app.get("/", (req, res) => res.render("index.ejs", {title: "foo"}));

app.get("/data", (req, res) => {
  res.json({data: (req.query.word || "") + Math.random()});
});

app.listen(
  app.get("port"),
  () => console.log(`running on port ${app.get("port")}`)
);
ggorlen
  • 44,755
  • 7
  • 76
  • 106