Data not showing on Handlebars - node.js

I have the script below which extracts the data from MongoDB:
router.get("/visualizarinscritos/:id", eEmpresa, (req,res)=>{
result = []
Vaga.findOne({_id: req.params.id}).then((vaga)=>{
//console.log(Object.values(JSON.parse(JSON.stringify(vaga.candidatos))))
Curriculo.find().then((curriculo)=>{
if(curriculo){
for(var r = 0; r < vaga.candidatos.length ; r++){
for(var i = 0; i < curriculo.length; i++){
if(vaga.candidatos[r] == curriculo[i].usuario){
result.push(curriculo[r])
}
}
}
res.render("empresa/viewcurriculos", {curriculo: result})
}else{
req.flash("error_msg", "Não há curriculos relacionados")
res.redirect("/empresa/vagas")
}
}).catch((err)=>{
req.flash("error_msg", "Houve um erro ao buscar usuários relacionados a vaga: "+err)
res.redirect("/empresa/vagas")
})
}).catch((err)=>{
req.flash("error_msg", "Houve um erro ao carregar vaga: "+err)
res.redirect("/empresa/vagas")
})})
I'm receiving the data as expected. I did a console.log and I'm getting it correctly:
[ {
_id: 60cabfad6494450bd0065877,
usuario: 60cabebfd90f8427c4840990,
experiencia: 'SAP Concur Reporting Analyst\r\n' +
'SAP SE | 07/22/2019 - Current.\r\n' +
'Support and develop reports on IBM Cognos\r\n' +
'\r\n' +
'Support team questions and handle issues\r\n' +
'\r\n' +
'Teach new colleagues\r\n' +
'\r\n' +
'Translate documents to Portuguese, English or Spanish.\r\n' +
'\r\n' +
'Create and support system automations\r\n' +
'\r\n' +
'Trilingual Service Desk Senior\r\n' +
'HCL Technologies | 02/27/2019 – 07/19/2019\r\n' +
'Teach news Service Desk Analyst\r\n' +
'\r\n' +
'Teach and remainder the team about process and new process or applications\r\n' +
'\r\n' +
'Answer the questions that the Analyst of Service Desk can ask\r\n' +
'\r\n' +
'Learn and participate of migrations of new applications\r\n' +
'\r\n' +
'Work on tickets that have a big priority\r\n' +
'\r\n' +
'Help key users solving problems and answering questions\r\n' +
'\r\n' +
'Verify the tickets that Service Desk done something and escalate it if necessary\r\n' +
'\r\n' +
'Bilingual Service Desk\r\n' +
'HCL Technologies | 05/22/2017 – 02/27/2019\r\n' +
'Support on applications that are homologated and used by the client\r\n' +
'\r\n' +
'Remote support on softwares\r\n' +
'\r\n' +
'Support on applications that are homologated and used by the client, O.S, networks and telecom\r\n' +
'\r\n' +
'improve the Knowledge base\r\n' +
'\r\n' +
'Answer emails, calls and chats according the demands\r\n' +
'\r\n' +
'Manage tickets\r\n' +
'\r\n' +
'Internship – Maintenance of computers and networks\r\n' +
'QI Escolas & Faculdades | 09/14/2016 - 05/18/2017\r\n' +
'Administrative routines\r\n' +
'\r\n' +
'Servers maintenance\r\n' +
'\r\n' +
'Maintenance of cabling and switch\r\n' +
'\r\n' +
'Remote support on applications\r\n' +
'\r\n' +
'Local support on hardware and Telecom area.',
educacao: 'Associate in Analysis and Systems Development\r\n' +
'Unisinos | 2017/2 - Current.\r\n' +
'\r\n' +
'IT\r\n' +
'QI Escolas & Faculdades | Completed at 2017',
certificacao: '>\r\n' +
'ITIL\r\n' +
'\r\n' +
'>\r\n' +
'Active Directory\r\n' +
'\r\n' +
'>\r\n' +
'Exchange\r\n' +
'\r\n' +
'>\r\n' +
'Windows Server and OS\r\n' +
'\r\n' +
'>\r\n' +
'Network maintenance/management\r\n' +
'\r\n' +
'>\r\n' +
'Hardware',
idioma: 'Porguese\r\n\r\nEnglish\r\n\r\nSpanish\r\n\r\nLIBRAS',
habilidades: 'Java\r\n' +
'\r\n' +
'SQL\r\n' +
'\r\n' +
'HTML/CSS\r\n' +
'\r\n' +
'JavaScript\r\n' +
'\r\n' +
'EJS\r\n' +
'\r\n' +
'NodeJS\r\n' +
'\r\n' +
'Android\r\n' +
'\r\n' +
'Angular\r\n' +
'\r\n' +
'PHP\r\n' +
'\r\n' +
'Cognos',
outros: 'Github: https://github.com/gabdonada\r\n\r\nFuncionou?',
__v: 0},undefined]
However, when trying to get the data using the Handlebars code below, the page is not showing values:
{{#each curriculo}}
<div class="card">
<div class="card-body">
<h4>{{curriculo.usuario.nome}}</h4>
<h4>{{experiencia}}</h4>
<small>Sobre: {{curriculo.experiencia}}</small><br>
<button class="btn btn-success">Visualizar Curriculo</button>
</div>
</div>
{{else}}
<h4>Não há curriculos registrados</h4>
{{/each}}
I tried by using and not using Each, but still not working. Do you know how to fix this?

Within an #each block, you need to use this to access the current array item. Therefore you should change your code to:
{{#each curriculo}}
<div class="card">
<div class="card-body">
<h4>{{this.usuario.nome}}</h4>
<small>Sobre: {{this.experiencia}}</small><br>
<button class="btn btn-success">Visualizar Curriculo</button>
</div>
</div>
{{else}}
<h4>Não há curriculos registrados</h4>
{{/each}}

The solution for this case is adding Async + Promise, as below. The res.render was redirecting to the page before the code completes. I also used .lean():
Router.get("/visualizarinscritos/:id", eEmpresa, (req,res)=>{
var result = []
Vaga.findOne({_id: req.params.id}).lean().then((vaga)=>{
Curriculo.find().lean().then( async (curriculos)=>{
if(curriculos){
const promises = []
for(const candidato of vaga.candidatos){
for(const curriculo of curriculos ){
promises.push(
new Promise((resolve) => {
if(candidato == curriculo.usuario){
result.push(curriculo)
}
resolve(candidato)
})
)
}
}
Promise.all(promises).then((resposta) => {
console.log(result)
console.log(result.usuario)
res.render("empresa/viewcurriculos", {teste: result})
})
}else{
req.flash("error_msg", "Não há curriculos relacionados")
res.redirect("/empresa/vagas")
}
}).catch((err)=>{
req.flash("error_msg", "Houve um erro ao buscar usuários relacionados a vaga: "+err)
res.redirect("/empresa/vagas")
})
}).catch((err)=>{
req.flash("error_msg", "Houve um erro ao carregar vaga: "+err)
res.redirect("/empresa/vagas")
})
})

Related

Express cannot process textarea value [duplicate]

This question already has answers here:
Textarea value not getting posted with form
(12 answers)
Closed 3 years ago.
I want to get value using post method in node.js using body-parser. But I always get undefined.
Below is my node.js code.
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
app.get('/form', function (req, res) {
html += "<form action='/thank' method='post' name='form1'>";
html += "<div id='divParent'>";
html += "<div id='div1' name='formset' class='formset'>";
html += "<p>Name: <input type= 'text' name='name'></p>";
html += "<p>Sex: Male <input type='radio' class='gender' name='gender' value='male'>"
html += " Female <input type='radio' class='gender' name='gender' value='female'></p>"
html += "<p>Email: <input type='text' name='email'></p>";
html += "<p>Address:<input type='text' name='address'></p>";
html += "<p>Mobile number:<input type='text' name='mobilno'></p>";
html += "<p>Note:</p>"
html += '<textarea rows="4" cols="50" name="note" id="note" form="form1"></textarea>';
html += "</div>";
html += "</div>";
html += "<input id='input1' type='submit' value='submit'>";
html += "<INPUT type='reset' value='reset'>";
html += "</form>";
...
}
app.post('/thank', urlencodedParser, function (req, res){
var reply='';
reply += "<br>Array length is : " + req.body.name.length;
reply += "<br>Your name is : " + req.body.name;
reply += "<br>Sex is : " + req.body.gender;
reply += "<br>Your E-mail id is : " + req.body.email;
reply += "<br>Your address is : " + req.body.address;
reply += "<br>Your mobile number is : " + req.body.mobilno;
reply += "<br>Your note is : "+ req.body.note;
console.log(req.body)
res.send(reply);
});
I can get the input value, but not textarea value.
Here's what I get when I console.log(req.body)
{ name: 'Roy',
gender: 'male',
email: 'roy#topscore.com',
address: 'Bali',
mobilno: '0821' }
Why body-parser can't get req.body.note? What's the problem?
I think the textarea is not really part of the form since you do not have a form with id "form1". Either remove the form attribute from the textarea or add the attribute id to the form.

Vuejs Filter String Replace

I have an image that i am binding the source to pull in dynamic data:
<img :src="'/public/images/' + media.client.name + '_' + media.client.id + '/' + media.type + '/' + media.fileName + '.' + media.ext " alt >
The media.client.name returns a string that has %20 instead of spaces.
I have created a filter:
removeSpecial(value) {
return value.replace("%20", " ");
}
How can I use this filter in the data binding of source please?
I have tried:
<img :src="'/public/images/' + media.client.name | removeSpecial + '_' + media.client.id + '/' + media.type + '/' + media.fileName + '.' + media.ext " alt >
and
<img :src="'/public/images/' + {{ media.client.name | removeSpecial }} + '_' + media.client.id + '/' + media.type + '/' + media.fileName + '.' + media.ext " alt >
Neither seem to work unfortunately.
You can make method which will return prepared url computed method like this:
imageUrl(media){
return '/public/images/' + media.client.name.replace("%20", " ") + '_' + media.client.id + '/' + media.type + '/' + media.fileName + '.' + media.ext;
}
Or if media is assigned in data you can use computed method which will return you same url
computed: {
imageUrl(){
return '/public/images/' + this.media.client.name.replace("%20", " ") + '_' + this.media.client.id + '/' + this.media.type + '/' + this.media.fileName + '.' + media.ext;
}
}
That would depend on how you want to decode the URI component. If this media data is populated dynamically (I suppose so), you could make a method for parsing and decoding it (see example below). If you need this decoder as a filter, however, here's an excerpt from the docs:
Filters should be appended to the end of the JavaScript expression, denoted by the "pipe" symbol.
So your best bet is probably to use a computed property so you can "pipe" it. And yes, you could utilize the native method decodeURIComponent() for this exact purpose.
Approach #1: Method only
new Vue({
el: '#app',
data() {
return {
rootPath: '/public/images/',
media: {
client: {
name: 'Music%20file%20with%20spaces',
id: 123
},
type: 'music-file',
fileName: 'some_music',
ext: 'mp3'
}
}
},
methods: {
getImgSource(media) {
// Destructures the properties for improved readability.
const { client, type, fileName, ext } = media;
const { name, id } = client;
// Uses template literals. Particularly useful for this situation
// where you have several, unique delimiters.
// Helps you see clearer how each of these URI components is combined.
return `${this.rootPath}${decodeURIComponent(name)}_${id}/${type}/${fileName}.${ext}`;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<!-- Commented out for demo purposes, because I don't have the file.
<img :src="getImgSource(media)" :alt="media.fileName" /> -->
<!-- Let's assume this is an image element -->
<div v-text="getImgSource(media)"></div>
</div>
Approach #2: Computed property + filter
new Vue({
el: '#app',
data() {
return {
rootPath: '/public/images/',
media: {
client: {
name: 'Music%20file%20with%20spaces',
id: 123
},
type: 'music-file',
fileName: 'some_music',
ext: 'mp3'
}
}
},
computed: {
mediaFile() {
const { client, type, fileName, ext } = this.media;
const { name, id } = client;
return `${this.rootPath}${name}_${id}/${type}/${fileName}.${ext}`;
}
},
filters: {
decodeName: window.decodeURIComponent
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<!-- Let's assume this is an image element -->
<div>{{ mediaFile | decodeName }}</div>
</div>
Hope that helps.

Change the default content of a site if the site is redirected

So I have a eventhandler for a website called "login" :
function _GetLoginEventHandler(req, res) {
var answer = _getHTMLSkeleton();
var dynamicAnswer;
if (isLogedIn == false) {
dynamicAnswer = "<h1>Login</h1>" + //creates a form for not logged users
"<form action='/login' method='post'>" +
"User name: <br>" +
'<input type="text" name="username" value="MickeyMouse">' +
"<br>" +
"Password: <br>" +
'<input type="password" name="password" value="geheim">' +
"<br><br>" +
'<input type="submit" value="Submit">' +
"</form> ";
answer = answer.replace('{title}', "Login");
answer = answer.replace("{body}", dynamicAnswer);
res.write(answer);
res.end();
}
else {
res.writeHead(302, { //if the user is loged it, it redirects to his "profile"
'Location': '/user'
});
res.end();
}
};
If the user is already logged in, it redirect him to a page called "user" which is in my case his profile:
function _GetUserEventHandler(req, res) {
var answer = _getHTMLSkeleton();
var dynamicAnswer;
if (isLogedIn == true) {
dynamicAnswer = "<h1>Logg Off</h1>" +
"<p>Your user id is: " + uID + "</p>" +
"<form action='/user' method='post'>" +
'<input type="submit" value="Submit">' + "</form>";
}
else
dynamicAnswer = "<h4>You are not allowed to see this content, you are not loged in </h4>";
answer = answer.replace('{title}', "User");
answer = answer.replace("{body}", dynamicAnswer);
res.write(answer);
res.end();
}
I want to check if the home site is redirected from (in this case) the login page so I can add to "answer" for example "You are succesfully logged in".
PS: The _getHTMLSkeleton returns the structur of a HTML page with placeholders
You can check if referrer header in your application is your login form:
req.headers.referer
if your app is setting referrer values (check origin .
or try setting header:
res.setHeader('fromLoginPage', 'true');
before redirecting user, and checking it later:
req.headers.fromLoginPage == true

DocusignAPI - Issue - Trying to push data to template before sending & it doesn't work

I have a text field labeled "RecipientName" in my template. I am trying to populate that field before sending to receipient. But it doesn't populate. I am using "DocuSign API - Signature Request from Template". I don't get any error, but it doesn't populate the field. Please help!
Here is my request Body & url
string url = "https://demo.docusign.net/restapi/v2" + "/accounts/" + accountId + "/envelopes";
string requestBody =
"<envelopeDefinition xmlns=\"http://www.docusign.com/restapi\">" +
"<status>sent</status>" +
"<emailSubject>DocuSign API - Signature Request from Template</emailSubject>" +
"<templateId>" + templateId + "</templateId>" +
"<templateRoles>" +
"<templateRole>" +
"<name>" + recipientName + "</name>" +
"<email>" + recipientEmail + "</email>" +
"<roleName>" + templateRole + "</roleName>" +
"<tabs>" +
"<textTabs>" +
"<tabLabel>RecipientName</tabLabel>" +
"<name>RecipientName</name>" +
"<value>Recepient Test</value>" +
"</textTabs>" +
"</tabs>" +
"</templateRole>" +
"</templateRoles>" +
"</envelopeDefinition>";
You're missing the inner <text> xml tag for your tab. Try this:
<textTabs>
<text>
<tabLabel>RecipientName</tabLabel>
<value>RecipientName</value>
</text>
</textTabs>
This should work, though as Andrew mentioned you should really just use the Name tag if you're trying to display the recipient's name.

Responsive rotating banner on SharePoint 2013

is there any tool or webPart to add banners to sharepoint 2013 that support responsiveness?
You don't need anything SP specific. I've used flexslider in the past for SP and otherwise. Just use REST to populate from your list and call flexslider in the ajax success callback.
(Too long for a comment) I do on my other machine - this is a 2010 example where I used SPServices to do the same thing. Same concept - generate your markup with the response data and apply flexslider after the markup is populated.
$(document).ready(function() {
$().SPServices({
operation: "GetListItems",
async: false,
webURL: "/",
listName: "Home Slider",
CAMLViewFields: "<ViewFields><FieldRef Name='ImageLink' /><FieldRef Name='Title' /><FieldRef Name='SubTitle' />"
+ "<FieldRef Name='LinkText' /><FieldRef Name='LinkURL' /><FieldRef Name='Description' />"
+ "</ViewFields>",
completefunc: function (xData, Status) {
var myslider;
var liHtml = "";
$(xData.responseXML).SPFilterNode("z:row").each(function() {
liHtml += "<li style='background:url(" + $(this).attr("ows_ImageLink") + ") no-repeat center top;'>"
+ "<div class='slideWrap'><div class='slideInnerWrap'>"
+ "<h2>" + $(this).attr("ows_Title") + "</h2>"
+ "<a href='" + $(this).attr("ows_LinkURL") + "' class='btn btnOrange btnLarge' >"
+ $(this).attr("ows_LinkText") + "</a>"
+ "</div></div>"
+ "</li>";
});
$("#sliders").append("<ul class='slides'>" + liHtml + "</ul>");
$('.flexslider').flexslider({
directionNav: true,
animation: "slide"
});
}
});
});

Resources