Specific value Array object from Mongodb into handlebars table

I’m trying to build a table with values from an Array of objects from mongodb, but I only can get every value and only need the specific value.

So I made a query like this

router.get("/arquiveExpense", ensureAuthenticated, (req, res) => {
  House.find({
    userID: req.user.id,
    expensesHouse: { $elemMatch: { status: "Private" } }
  }).then(house => {
    console.log(house);
    res.render("houses/arquiveExpense", {
      house: house
    });
  });
});

I want to retrieve the specific value from expensesHouse with status ‘Private’.

And in handlebars I have this structure

<tbody>

                    <tr>
                        {{#each house}}

                        <td>{{expenseType}}</td>
                        <td>{{price}}€</td>
                        <td>{{payAt}}</td>

                        <td>{{formatDate date 'MMMM Do YYYY'}}</td>
                        <td>
                            <a href="/houses/showExpense/{{id}}" id="detailsExpense"
                                class="btn btn-outline-light mb-3"><i class="fas fa-eye mr-2"></i>Details
                            </a>
                        <td>
                            <a href="/houses/editExpense/{{id}}" id="editExpense" class="btn btn-outline-light mb-3"><i
                                    class="fas fa-edit mr-2"></i>Edit
                        </td>
                    </tr>

                    {{else}}
                    <p>No expenses</p>
                    {{/each}}
                </tbody>

And after this handlebars, this is the result

The Schema structure is the follow

So I want to show in the web page the value from expensesHouse with the Status ‘Private’.

How can I change my code to retrieve only this value ?

Did you try like this?

expensesHouse: { $elemMatch: { status: { $eq: 'Private' } } }
1 Like

Didn’t work too… I retrieve the private match but only one and I need every register with private status…

It’s not clear what’s your goal. Do want to show all the private expenses of all the houses with specific userID?

1 Like

I think the confusion is that you originally said you only wanted the one value with status equal to “Private”. You were already using $elemMatch which limits the value returned to a single item of the array.

1 Like

But if I have two or more values with status ‘Private’ I want them too…

My goal is:

I have my array with multiple expenses, privates and public and I want to retrieve all info with specific userID and status = ‘Private’ or ‘Public’.

So this thing will find all the houses where userID matches and expensesHouse will have at least one element with status set to 'Private':

House.find({
    userID: req.user.id,
    expensesHouse:  { $elemMatch: { status: { $eq: 'Private' } }
})

Then in then():

.then((houses) => {
  res.render('houses/arquiveExpense', { house: filterByExpenses(houses, 'Private') });
});

function filterByExpenses(houses, expenseStatus) {
  return houses
    .map((house) => ({
      ...house,
      expensesHouse: house.expensesHouse
        .filter(({ status }) => status === expenseStatus)
    }));
}

I guess this will get you the right result, however your handlebars code is hugely unprepared - for starters, you have nested array in each house, therefore you need two #each loops, one for each house and one for each expense. Secondly they both need to be outside <tr> tag.

Good luck!

2 Likes

I just figured out after the ‘RandellDawson’ answer if I use the $elemMatch I never see all the results.
So i change my router to something like this:

outer.get("/dashboard", ensureAuthenticated, (req, res) => {
  House.aggregate([
    {
      $match: { members: req.user.id }
    },
    {
      $unwind: "$expensesHouse"
    },
    {
      $match: { "expensesHouse.status": "Public" }
    }
  ]).then(house => {
    console.log(house);
    res.render("houses/dashboard", {
      house: house
    });
  });
});

And in my

inside handlebars I have something like this:
<tbody>
                            {{#each house}}
                            <tr>

                                {{!-- {{#each expensesHouse}} --}}
                                <td>{{expensesHouse.expenseType}}</td>
                                <td>{{expensesHouse.price}}€</td>
                                <td>{{expensesHouse.payAt}}</td>

                                <td>{{formatDate date 'MMMM Do YYYY'}}</td>
                                <td>
                                    <a href="/houses/showExpense/{{id}}" id="detailsExpense"
                                        class="btn btn-outline-light mb-3"><i class="fas fa-eye mr-2"></i>Details
                                    </a>
                                <td>
                                    <a href="/houses/editExpense/{{id}}" id="editExpense"
                                        class="btn btn-outline-light mb-3"><i class="fas fa-edit mr-2"></i>Edit
                                </td>
                            </tr>
                            {{!-- {{/each}} --}}
                            {{else}}
                            <p>No expenses</p>
                            {{/each}}
                        </tbody>

So the problem is solved ! :slight_smile: