Meteor Blaze iterate over dynamically created object - node.js

I'm trying to iterate with Blaze over dynamically created object. I have the collection and the object, but I can't display the data in my tables and I don't understand why.
Here's my code to retrieve the object :
In my Template Helpers :
fields: ()=> {
var collectionSelected = FlowRouter.current().params.collectionName;
// var data = Mongo.Collection.get(collectionSelected).find().count();
var collectionObject = Collections.findOne({name: collectionSelected});
console.log(Collections.findOne({name: collectionSelected}));
return Collections.findOne({name: collectionSelected});
},
values: ()=> {
var collectionSelected = FlowRouter.getParam('collectionName');
var collectionObject = Collections.findOne({name: collectionSelected});
var dataArray = [];
var data = Meteor.call('findElmt', collectionSelected, function(err, res){
console.log('VALUES : ');
console.log(res);
return res;
});
},
The findElmt method :
findElmt(collectionName){
if (global.hasOwnProperty(collectionName)){
var res = Mongo.Collection.get(collectionName).find().fetch();
console.log(res);
return res;
}
else {
global[collectionName] = new Meteor.Collection(collectionName);
var res = Mongo.Collection.get(collectionName).find().fetch();
console.log(res);
return res;
}
}
And finally the way I'm trying to display it with Blaze :
<table data-toggle="table" data-show-columns="true" data-search="true" data-pagination="true">
{{#with fields}}
{{#if Template.subscriptionsReady}}
<thead>
<tr>
{{#each fields.fieldsName}}
<th data-sortable="true">{{this}}</th>
{{/each}}
</tr>
</thead>
{{else}}
<p>Loading...</p>
{{/if}}
{{/with}}
<tbody>
{{#each values}}
<tr>
{{#each valueString in values.items}}
<td>{{valueString}}</td>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
If you have any advice on what I'm doing wrong, thank you !
EDIT 1 : I added the fields helper !

Supposing that values is an array of JsonObject with the field items, you are iterating the wrong way.
When using {{#each}} and not {{#each in}} you can access directly your properties with itemsor with this.items.
If values is an array of JsonObject :
<tbody>
{{#each values}}
<tr>
{{#each valueString in this.items}} // values.items -> this.items
<td>{{valueString}}</td>
{{/each}}
</tr>
{{/each}}
</tbody>
If values is a JsonObject, you can use with :
<tbody>
{{#with values}}
<tr>
{{#each valueString in this.items}} // values.items -> this.items
<td>{{valueString}}</td>
{{/each}}
</tr>
{{/with}}
</tbody>
Then to have a reactive returned value with Method call you can use the following package :
https://atmospherejs.com/simple/reactive-method

Thank you a lot for your help, I finally nailed it.
Here's the final code for the future lost soul like me !
Template Helpers :
fields: ()=> {
var collectionSelected = FlowRouter.current().params.collectionName;
// var data = Mongo.Collection.get(collectionSelected).find().count();
var collectionObject = Collections.findOne({name: collectionSelected});
console.log(Collections.findOne({name: collectionSelected}));
return Collections.findOne({name: collectionSelected});
},
values: ()=> {
var collectionSelected = FlowRouter.getParam('collectionName');
var collectionObject = Collections.findOne({name: collectionSelected});
var dataArray = [];
console.log(ReactiveMethod.call("findElmt", collectionSelected));
return ReactiveMethod.call("findElmt", collectionSelected);
}
The server side FindElmt method didn't change,
and finally the Blaze code :
<table data-toggle="table" data-show-columns="true" data-search="true" data-pagination="true">
{{#with fields}}
{{#if Template.subscriptionsReady}}
<thead>
<tr>
{{#each fields.fieldsName}}
<th data-sortable="true">{{this}}</th>
{{else}}
{{! will this fix this issue? }}
{{/each}}
</tr>
</thead>
{{else}}
<p>Loading...</p>
{{/if}}
{{else}}
{{! will this fix this issue? }}
{{/with}}
{{#with values}}
<tbody>
{{#each values}}
<tr>
{{#each valueString in this.items}}
<td>{{valueString}}</td>
{{else}}
{{! will this fix this issue? }}
{{/each}}
</tr>
{{else}}
{{! will this fix this issue? }}
{{/each}}
</tbody>
{{else}}
{{! will this fix this issue? }}
{{/with}}
</table>

Related

handlebars.js build in helper #each not working

I am using expressjs and mongoose in backend and handlebars as view engine.
Here is my method in index js
const router = require('express').Router()
const Product = require('../../models/Products')
// Products
router.get('/products',async (req, res) => {
try{
const products = await Product.find()
res.status(200).render('products',{products})
}catch(err){
res.status(400).render('products')
}
})
Documents inside product collection is like this:
[
{
_id: new ObjectId("632d74a0b828b58a1d25b047"),
title: 'Footballs',
description: 'This is a nice product.',
images: [
'/product-images/1663923360491/image1.png',
'/product-images/1663923360491/image2.png'
],
categories: [ 'football', 'balls', 'sports' ],
price: 800,
stock: 300,
createdAt: 2022-09-23T08:56:00.546Z,
updatedAt: 2022-09-23T08:56:00.546Z,
__v: 0
}
]
And here is the foreach sentence at index.hbs
<table>
<thead>
<tr>
<td>Date</td>
<td>Product</td>
<td>Price</td>
<td>Options</td>
</tr>
</thead>
<tbody>
{{#each products}}
<tr>
<td>{{this.createdAt}}</td>
<td>{{this.title}}</td>
<td>₹{{this.price}}</td>
<td>
<button>edit</button>
<button>delete</button>
</td>
</tr>
{{/each}}
</tbody>
</table>
This code is not working (td tag is empty). But when I put {{#index}},the index of the current array item is displaying but other values are not displaying.
{{#each products}}
<tr>
<td>{{#index}}</td>
<td>{{this.title}}</td>
<td>₹{{this.price}}</td>
<td>
<button>edit</button>
<button>delete</button>
</td>
</tr>
{{/each}}
Any help is greatly appreciated, thanks in advance!
You don't need to use this here:
{{#each products}}
<tr>
<td>{{createdAt}}</td>
<td>{{title}}</td>
<td>₹{{price}}</td>
<td>
<button>edit</button>
<button>delete</button>
</td>
</tr>
{{/each}}
If using mongoose, this issue can be solved by using .lean() to get a json object (instead of a mongoose one):
const products = await Product.find().lean()
res.status(200).render('products',{products})

How can i render data on change?

I'm trying to build a project in nodejs as server and firebase as my realtime db and having some problems with forwarding the data to my html.
I getting the error:
Cannot set headers after they are sent to the client
on change
I'm trying to pass the updated arr to html but can't find a way to do that.
server.js:
const locksRef = await firebase.firebase.database().ref('locks')
let arr = []
//get list of locks
const t = locksRef.on('value', (data) => {
tempResult3 = data.val()
result3 = []
const numOfKeys = Object.keys(tempResult3)
numOfKeys.forEach((x) => {
result3.push(tempResult3[x])
})
result3.forEach((k) => {
myLocks.forEach((my) => {
if (k.id == my) {
arr.push(k)
}
})
})
res.render('ListOfLocks', { arr })
})
html
<body>
<h1>ListOfHouses</h1>
<table border="1px solid black">
<thead>
<th>Name And Address</th>
</thead>
<tbody>
{{#each arr}}
<tr>
<td id="data"> {{name}} - {{address}}</td>
<td>
<form action="/seekKeys" method="post"><button name="{{locks}}" type="submit">LookForKey</button>
</form>
</td>
</tr>
{{/each}}
</tbody>
</table>
</body>

Updata table html EJS + Nodejs + Expressjs

I have an application nodejs + expressjs + ejs.
I am building a history search screen, my question is how to update my ejs html table with the values ​​returned in the response.
Uploading the screen with the values ​​is working, but when I enter the filters and search, I would like to update my table.
In the example below is how to use to load the html the first time with the data of the query, I would like to fill in an initial and final date and click on searching and updating the html.
EJS HTML
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label for="dataPrimayID">Date Primary</label>
<input type="text" class="form-control datepickerDefault" id="dataPrimayID" name="dataPrimary" maxlength="250">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for="dataFinalID">Date Final</label>
<input type="text" class="form-control datepickerDefault" id="dataFinalID" name="dataFinal" maxlength="250">
</div>
</div>
<div class="col-md-2">
<a id="btnSearch" class="btn btn-primary">Search</a>
</div>
</div>
<div class="row">
<div class="table-responsive col-md-12">
<table id="dataTableHistoricoID" class="table table-striped" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th>Name</th>
<th>LastName</th>
</tr>
</thead>
<tbody>
<% if(data.length > 0){ %>
<% for ( var i = 0 ; i < data.length ; i++){ %>
<tr>
<td>
<%= data[i].name%>
</td>
<td>
<%= data[i].lastname%>
</td>
</tr>
<% } %>
<% } %>
</tbody>
</table>
</div>
</div>
ROUTER
var express = require('express');
var router = express.Router();
var historyController = require('../controllers/history-controller');
router.get('/find', historyController.findHistory);
module.exports = router;
Controller
db.query(sql, function (err, rows) {
if (err) {
var message = err.message;
console.log(message);
return res.status(500).send(message);
}else {
var data = rows;
res.render('history/search-history', {data: data});
}
});
EJS is static after compiling, you can't change it on backend-side. There are two ways of it.
Refreshing the page every time you want to render new content.
Implement client-side JS code that will handle api requests and render new elements.
For example, using Jquery:
$.post(url, (result) => {
let data = JSON.parse(result);
let innerHTML = '';
for (let item of data) {
innerHTML += `<tr>
<td>
${item.name}
</td>
<td>
${item.lastname}
</td>
</tr>`;
}
$('#dataTableHistoricoID tbody').html(innerHTML)
};

KrakenJs with Dust Template looping through object Error

I should Have got the else part but I am getting the error: Expected end tag for cart.items but it was not found. At line : 21, column : 35. I don't know where is the problem everything is fine may be indentation error please look out the code and suggest me. thanks there is also attached screen shot of the error.
this is my dust file:
{>"layouts/master" /}
{<body}
<div class="row">
<div class="container">
<h2>Your Cart</h2>
{?cart.items}
<table>
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Total</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{#cart.items}
<tr>
<td>{title}</td>
<td>{.qty}</td>
<td> ${#math key="{.price}" method="multiply" operand ="{.qty}"}</td>
<td>Remove</td>
</tr>
{/cart.items}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
<h4> Total <strong>${cart.total}</strong></h4>
</div>
<div class="col-sm-6">
</div>
</div>
{:else}
<p>There is no Items in your cart</p>
{/cart.items}
</div>
</div>
{/body}
this is my controller
'use strict';
var Book = require('../models/bookModel');
var Category = require('../models/categoryModel');
module.exports = function (router) {
router.get('/', function (req, res) {
var cart = req.session.cart;
var displayCart = {
items: [], total: 0
};
var total = 0;
//get total
for(var item in cart){
displayCart.items.push(cart[item]);
total += (cart[item].qty * cart[item].price);
}
displayCart.total = total;
res.render('cart/index', {cart: displayCart});
});
});
I am Getting this error:
The math helper should be closed. E.g:
{#math key="{.price}" method="multiply" operand ="{.qty}" /}

Creating modal with Backbone - passing variable to template

I am trying to figure out if I can pass a variable to a template.
Here is the template:
<script type="text/template" id="modal-template">
<table class="table">
<thead>
<tr>
<th>Team Name</th>
</tr>
</thead>
<tbody>
<% for(var i=0; i
<XXX.length
; i++) { %>
<tr>
<td>
<a href='/users/<%=user._id%>/teams/<%= teams[i]._id%>/teamDashboard'>
<%= XXX[i].teamName %>
</a>
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</script>
I want to pass the above template a variable, let's say it's the variable identified above and below named XXX.
<script>
$(function($) {
var XXX = {};
//how can I pass the template the variable XXX???
var Modal = Backbone.Modal.extend({
template: _.template($('#modal-template').html()),
cancelEl: '.bbm-button'
});
$('.ImportTeamsFromTeamSnap').on('click', function(){
var modalView = new Modal();
$('.app').html(modalView.render().el);
});
});
</script>
Basically I want the template to render differently depending on the variable XXX. This could be a handlebars template, or any type of template that makes it possible.
Is this possible?
You can pass a Model to the modal. Something like this:
<script>
$(function($) {
var XXX = {};
//how can I pass the template the variable XXX???
var Modal = Backbone.Modal.extend({
template: _.template($('#modal-template').html()),
cancelEl: '.bbm-button'
});
$('.ImportTeamsFromTeamSnap').on('click', function(){
var MyModel = Backbone.Model.extends({});
var modalView = new Modal();
modalView.model = new MyModel(XXX);
$('.app').html(modalView.render().el);
});
});
</script>

Resources