Cannot connect frontend and backend in Express, Node and Javascript

Thank you for taking time to read my question. Currently I am working on using a dropdown list using “select” tag for the user to select from. and totally stuck on the following. localhost, all other pages and functions working properly . yet Cannot connect frontend and backend in Express, Node and Javascript

Any help would be appreciated .

Handlebar template I use is as follows.

<div class="container center">
  <div class="row">
  <h3 class="flow-text">Search for items you can exchange your item with</h3>
  <div class="col s12">
    <label>Search by Category</label>
  <select id="category" class="browser-default" onchange="getItems()">
    <option value="" disabled selected>I am looking for...</option>
    <option value="2">Vegetables</option>
    <option value="3">Clothes</option>
    <option value="4">Fruits</option>
    <option value="1">Other</option>
  </select>
  </div>
</div>

<div class="row">

{{#each editedItems as |i|}}
<div class="col s12 m4">
      <!---->
      <div class="card">
        <div class="card-image">
          <img src="/images/strawberry.jpg">
          <span class="card-title">{{i.title}}</span>
          <a class="btn-floating halfway-fab waves-effect waves-light red" href="/item/{{i.id}}"><i class="material-icons">zoom_in</i></a>
        </div>
        <div class="card-content">
          <p class="truncate">{{i.description}}</p>
        </div>
      </div>
      <!---->
    </div>
{{/each}}

</div>

</div>

<script src="/js/searchItems.js"></script>

On the change of the selection javascript will run a function called get items in the /js/searchItems.js. I checked wheather the script is linked by using a simple alerts. One each change those alerts worked before I put the actual function code.

searchItems.js has the following code.

function getItems() {
    const select = document.getElementById('category');
    let option = select.options[select.selectedIndex];
    let categoryId = option.value;

    searchByCategory(categoryId);
   
}

const searchByCategory = async (categoryId) => {
    const response = await fetch(`/items/${categoryId}`, {
      method: 'GET',
      headers: { 'Content-Type': 'application/json' },
    });
  
    if (response.ok) {
      console.log("Response ok");
    } else {
      console.log("Error");
    }
  };

And in the backend following route is written to get the items by using this category id taken from the option value in the dropdown list.

router.get('/items/:category', async (req, res) => {
  try {
      const categoryId = req.params.category;
      const existingItems = await Item.findAll({
      where:{
          category_id : categoryId
      },
      order: [['id','DESC']],
    });
    
      const editedItems = existingItems.map((item) => item.get({ plain: true }));
    
      res.render('search', { 
          editedItems, 
          logged_in: req.session.logged_in 
    });
  } catch (err) {
    res.status(500).json(err);
  }
});

All other routes in the same route file are working as expected. I tried to simulate this route using Insomina Core and it rendered the page as I expected.

But in the localhost, all other pages and functions working properly. But, when I change the options in the dropdown list (as per the screenshot below), items related to categories would not appear.

enter image description here

But it gives “respose ok” — looking at the console as follows.

enter image description here

I am using handlebars as a templating engine, Express server, MySQL and Nodejs.

Any support would be much appreciated. Thank you very much.

Answer

You are mixing up two types of HTTP request. An XMLHttpRequest (AJAX) and a regular HTTP request.

You are calling using ajax, but you are responding from the server as if it were a normal page view. Normally, in Express, you’d respond to an ajax request using response.send([body]) or by using one of the convenience methods such as response.json([body]). These typically format the response body some way and/or add some headers, but they are fundamentally all the same. I strongly suggest you browse the linked page to help your understanding.

Your browser handles “normal” http requests by rendering them as a page. But your ajax lib, (in this case fetch) is getting the response and doing nothing with it. Typically, you’d write some JavaScript to handle the response, i.e. parse the body and manipulate the page in some way.

However, since you are returning HTML and not JSON, you could possibly inject this HTML into a part of the page. See innerHTML. But this is arguably an archaic way to do it, I’d suggest having your initial template be manipulated purely though JavaScript.