Hello, why with findOne (nodejs, mongodb) my ejs condition gives me that the first element in my databasse

folder controllers

 const getAnnonce = (req, res) =>{
           
          const departement = req.query.departement
         
          // console.log(departement);
          Annonce.findOne({departement: departement}, (err, docs) =>{
            if(err) throw err
            // console.log(docs);
            res.render('annonce', {docs: docs})
          })
             
  }

folder router

router.get('/search', AnnonceController.getAnnonce)

file page home

   <form action="/search" method="GET" class="form-inline">
            <label  class="m-1" for="departement">
             <span class="homeSelect btn btn-warning">Entrer votre département pour bénéficier des biens offerts par votre voisin</span> 
            </label>
            <div class="input-group w-100">
              <select class="form-select" aria-label="Default select example" name="departement" id="departements">
                <option value="Ain">Ain</option>
                <option value="Hautes-Alpe">Hautes-Alpes</option>
                <option value="Alpes-Maritimes">Alpes-Maritimes</option>
           
              </select>
              <div class="input-group-btn">
                <button class="btn btn-info float-right">submit</button>
              </div>
            </div>
    </form>

file page condition ejs

<div class="row">
  <% if(docs)   {%>
   <div class="row">
   <div class="col-7 mt-3">
    <div class="card">
     <div class="card-horizontal">
     <div class="img-square-wrapper">
          <img class="" style="width: 200px; height: 100%;" src="<%= docs.image1Upload %>" />
      </div>
     <div class="card-body">
        <h6 class="card-title">
            <i class='fas fa-american-sign-language-interpreting text-danger'></i>
             <%= docs.titreBien %>
        </h6>
       <h6 class="card-title">
            <i class='fas fa-american-sign-language-interpreting text-success'></i>
           <%= docs.Categories %>
      </h6>
     <p class="card-title"> 
          <i class='fas fa-american-sign-language-interpreting text-primary'></i>
          <%= docs.address %> 
     </p>
     <h6 class="card-title badge bg-warning mt-5"> 
            <%= docs.date %> 
     </h6>
    </div>
    </div>
    </div>
   </div>
   </div>

<%} else  {%>
       <div style="position: relative;" class="bg-white text-dark p-5 mt-5" data-aos="fade-right">
      <form action="/search" method="GET" class="form-inline">
         <label  class="m-1" for="departement">
         <span class="homeSelect btn btn-warning">Entrer votre département pour bénéficier des biens offerts par votre voisin</span> 
        </label>
          <div class="input-group w-100">
          <select class="form-select" aria-label="Default select example" name="departement" id="departements">
            <option value="Ain">Ain</option>
             <option value="Aisne">Aisne</option>
              <option value="Allier">Allier</option>
               <option value="Alpes-de-Haute-Provence">Alpes-de-Haute-Provence</option>
               <option value="Hautes-Alpe">Hautes-Alpes</option>
               <option value="Alpes-Maritimes">Alpes-Maritimes</option>
            </select>
            <div class="input-group-btn">
               <button class="btn btn-warning float-right"><i class='fas fa-search' style='color:rgb(56, 56, 53)'></i></button>
            </div>
            </div>
       </form>
       </div>
     <div class="jumbotron bg-white text-dark mt-1 mb-5">
             <h3 class="text-center">ERROR 404, laBonte ne prend qu'en charge les departements de la France</h3>
          </div>
  <%}   %>

 </div>

I’m slightly confused about the problem. The title essentially is asking “why does findOne return the first element in the database”. The issue is what do you expect it to do instead of returning the first element? If the first element matches your query (the department matches) then its working as intended.

From the code it looks like maybe you want multiple documents returns, as you named your callback variable docs. If this is the case change findOne to find, which will return the array of docs that match rather than just the first one.

If that isn’t what you want, I’d provide more detail :slight_smile:

2 Likes

actually you are right i have to used find but if i use it i couldn’t use a req.query which will make a condition
example if the user selects a city which is not in the database or which does not exist I want it to return error.
that’s why I use findOne

I’m not sure I understand. findOne will only ever give you one result. Do you need more than one result? If so, you will need to use find. You should be able to check if the output from find didn’t contain anything, right?

in fact I believed that with findone normally if in a city there are several advertisements it should display all (in the database)

I tested it gives me the first ad that is in the database

Yeah, findONE will only find one result, the first result it finds.

at least I wanted a condition that will allow if the city does not exist he tells you

You should be able to check the the result from find to see if you got any results back.

if I get everything with find but if I try in the url to type a city which is not in the input select for the cities in fact it displays nothing but no error.
that’s why I’m trying not to use find

If you want multiple results, then findOne will not work. It just won’t. You can’t make findOne return any more than one result.

But you can make and throw your own error if your find returns no results.

I think I got what you really want → A function that return true or false whether a department exists in the database. right ?

I will simplify it for the purpose of didatics :slight_smile:


const getAnnonce = async (req, res) =>{
           
          const departement = req.query.departement
          const isThereAtLeastOne = await Annonce.findOne(
                                      {departement: departement} 
                                    )
          return ( !! isThereAtLeastOne )          
  }
1 Like

Didn´t test it tho :wink:

it’s very good but in fact that’s not that my problem is the find which returns everything even if the department does not exist

I think you should use find and check if the result is defined and has length > 0. Then you can make and throw your own error if nothing was found.

2 Likes

Now things got confused.

If the database is of departments, a null department won´t return anything

But, maybe the database is not departments that you want. What other document/table is in the database?

a big thank you I found the solution
here is

   <div class="row">
      <% if(docs.length > 0)  {%>
        <% for(docs of docs)   {%>
         
          <div class="row">
            <div class="col-7 mt-3">
                <div class="card">
                    <div class="card-horizontal">
                        <div class="img-square-wrapper">
                          <img class="" style="width: 200px; height: 100%;" src="<%= docs.image1Upload %>" />
                        </div>
                        <div class="card-body">
                          <h6 class="card-title">
                            <i class='fas fa-american-sign-language-interpreting text-danger'></i>
                            <%= docs.titreBien %>
                          </h6>
                          <h6 class="card-title">
                            <i class='fas fa-american-sign-language-interpreting text-success'></i>
                            <%= docs.Categories %>
                          </h6>
                          <p class="card-title"> 
                            <i class='fas fa-american-sign-language-interpreting text-primary'></i>
                            <%= docs.address %> 
                          </p>
                          <h6 class="card-title badge bg-warning mt-5"> 
                            
                            <%= docs.date %> 
                          </h6>
                        </div>
                    </div>
                </div>
            </div>
          </div>
          <%} %>
  
        <%} else  {%>
          <h1 class="text-white">error</h1>
       <%}  %>

Thanks for your help

Try this

const getAnnonce = async (req, res) =>{

      const departement = req.query.departement
      const response = await Annonce.findOne(
                                  {departement: departement} 
                                )
      return response          

}