Nikhil Savaliya
Nikhil Savaliya

Reputation: 2166

Express+mongoose: Populate data from array of object

I am trying to send name and one array as a response to handlebar page.

I want to display data in a table,

Mongoose Model

const Bank = new Schema({
  sBankName: String,
  sBranch: [
    {
      sBranchName: String,
      sBranchDetail: String,
    }
  ],
  sBankDetail: String,
  dCreatedDate: { type: Date, default: Date.now },
  updated_at: { type: Date, default: Date.now }
});

Router to get page

router.get("/branch_data", isAdminOnly, ensureAuthenticated, (req, res) => {
  var sBranch = [];
  Bank.find({})
    .populate("sBranch")
    .exec(function(err, Bank) {
      //var Bankf = JSON.stringify(Bank,null,"\t");
      for (var i = 0; i <= Bank.length; i++) {
        sBranch.push(Bank[i]);
      }
    });
  console.log(sBranch);
  res.render("branch_data", {
    user: req.user,
    admin: req.user.eUserType,
    sBranch: sBranch
  });
});

branch_data.handlebars

<table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%">
   <thead>
      <tr>
         <th>No.</th>
         <th>Bank</th>
         <th>Branch Name</th>
         <th>Branch Detail</th>
         <th>Action</th>
      </tr>
   </thead>
   <tbody>
      {{sBranch}}
      {{#each sBranch}}
      <td>1</td>
      <td>{{this.sBankName}}</td>
      {{#each this.sBranch}}
      <td>{{this.sBranch.sBranchName}}</td>
      {{/each}}
      <td>{{this.sBranch}}</td>
      <td>
         <textarea cols="50" rows="1" class="form-control" readonly></textarea>
      </td>

      </tr>
      {{/each}}
   </tbody>
</table>

I want to get BankName, BranchName and Branchdetail from the database and want to print in a table where one bank can have multiple branches.

can anyone suggest the best way to do this?

Upvotes: 0

Views: 1146

Answers (1)

Cisco
Cisco

Reputation: 22952

You are close. Two issues:

  1. Incorrect usage of .populate().

If your schema was defined as:

const Bank = new Schema({
  sBankName: String,
  sBranch: [{
    type: Schema.Types.ObjectId,
    ref: 'SomeOtherSchema'
  }],
  sBankDetail: String,
  dCreatedDate: { type: Date, default: Date.now },
  updated_at: { type: Date, default: Date.now }
});

Then you would need to call .populate('sBranch') which will give you the full sBranch object. Otherwise it would just give you and ObjectId.

  1. Your call to res.render will execute BEFORE your mongoose query is complete. This will result in the sBranch array you defined to always being empty. async-await example given below with error handling omitted:

-

router.get("/branch_data", isAdminOnly, ensureAuthenticated, async (req, res) => {
  // This is already an array. No need to loop and add to another array.
  const sbranch = await Bank.find({}).exec();

  res.render("branch_data", {
    user: req.user,
    admin: req.user.eUserType,
    sBranch: sBranch
  });
});

Upvotes: 2

Related Questions