nodeJS how to use router to add icon tag into pug file? - node.js

Hello I think it's easier to show partial lines of my code.
What I'm trying to do is when I input a zipcode, the right icon will show.
I'm using https://erikflowers.github.io/weather-icons/ this git.
for example: if NY weather condition says clear
weather condition in weather.pug should be like i.wi.wi-night-sleet
is it possible to add class name in icon tag from topic.js? or
can I use equal statement in pug flie like - if text=='clear' i.wi.wi-night-sleet
topic.js
router.post('/weather', function(req,res){
let url = `http://api.openweathermap.org/data/2.5/weather?zip=${req.body.zipcode}&units=imperial&appid=${apiKey}`
request(url, function (err, response, body) {
if(err){
res.status(500).send('Internal Server Error');
console.log('error: ' ,err);
} else {
if(req.body.zipcode.length != 5) {
res.render('topic/weather', {text: "Zipcode does not exist"})
} else {
let weather = JSON.parse(body)
let temp = weather.main.temp
let location = weather.name;
let day_weather = weather.weather[0].main;
let message = `It's ${weather.main.temp} degrees in ${weather.name}!`;
//below this I want to call icon tag that has a class name
res.render('topic/weather', {text: location + " : " + day_weather, weatherCondition: `i.wi.wi-night-sleet`});
}
}
});
})
weather.pug
extends ./homepage
block navigate
div.container-fluid
div.row.row-centered
p= text
//- space 넣을떄
= " "
if text
= date
div.col-lg-6.col-centered
form.form-group(action='/weather', method='post')
p
input(type='text', class="form-control", id="zipcode",name='zipcode', placeholder='zipcode')
p
button(type='submit', class="btn btn-primary btn-lg" style='margin-right: 10px;') Login

In your route just pass the identifying part of the icon you need:
res.render('topic/weather', {text: location + " : " + day_weather, weatherCondition: "night-sleet"});
Then here's what your pug template needs to look like:
i.wi(class= 'wi-' + weatherCondition)
or
i(class= 'wi wi-' + weatherCondition)
Either of those lines of pug will produce the same html:
<i class="wi wi-night-sleet"></i>

Related

Text input elements returning 'undefined' to .csv file

EDIT: I figured the problem out. It had turned out I was appending the items to themselves. The correct method I worked out would be to make a new variable as such:
var form = document.getElementById("listItems");
and then editing the document.body.appendChild(itemName); to
form.appendChild(itemName) and form.appendChild(itemQuantity) respectively.
For context, the call to the backend looked as such:
<form action="/buy" method=post id="listItems">
<input type="submit" value="Send">
</form>
When creating text boxes, I save the contents to a .csv file, however when I access these files I am returned a value of 'undefined'.
I looked into the code, and found that the input is saving itself as undefined no matter what was put in the text box.
Specifically these text boxes,
<script>
function addItems(){
var itemName = document.createElement("input");
itemName.setAttribute('type', 'text');
itemName.placeholder = "itemName";
document.body.appendChild(itemName);
var itemQuantity = document.createElement("input");
itemQuantity.setAttribute('type', 'text');
itemQuantity.placeholder = "itemQuantity";
document.body.appendChild(itemQuantity);
}
</script>
var itemName and itemQuantity show up in console.log and in the file as undefined values.
What should've happened was that when I ran:
var itemN = req.body.itemName;
var itemQ = req.body.itemQuantity;
await fs.appendFile('receipt.csv', "\n" + itemN + " " + itemQ, err => {
if (err) {
console.error(err);
}
console.log(itemN, itemQ);
// done!
})
It should have appended to the file 'receipt.csv' as ItemN + ItemQ as a string, however when accessed the file shows the submitted text as: Undefined Undefined.

Missing single quote while exporting pdf using Kendo react - PDFExport

Are you ready to refill your bottles?
Yes - I’m ready
Would you like to talk to the specialist?
No, I m all set!
const dynamic_question = props.oResponse.filter((item: any) => item.dynamic_question_status === true);
const CommonTrimming = (props: { value: string }) => {
let temp = props.value
.replace(/{*/g, '')
.replace(/}*/g, '')
.replaceAll(/'*/g, '')
.replace(/&/g, '&')
.replaceAll('\\n', '<br/>')
.replaceAll(',', '<br/>');
console.warn("executing or not ? ", temp);
return <div dangerouslySetInnerHTML={{ __html: temp }}></div>;
};
`
i have used to make common trimming.
here in second example we're missing single quote.
it should come in downloaded pdf.

Why me subscribe method in angular is not working?

I'm new in Angular, Nodejs and I was doing a CRUD app of txt files
I have to list all the files in a list, if you click one file need to display the data on a 'P'aragraph
My document component
getDocuments() - returns an array of all files in a path
getOneDOcument(name) -> get all the data of a file given "name"
getData(name) -> have to send the data to the paragraph with the id _> "paragraph_content"
getDocuments(){
this.DocumentService.getDocuments()
.subscribe(res => {
this.DocumentService.documents = res as Document[]
console.log("dentro del susbcribe");
console.log(res);
});
console.log("Fuera del subscribe");
}
getOneDocument(name : String){
console.log("NOO");
this.DocumentService.getOneDocument(name).subscribe(res => {
this.DocumentService.documentSelected = res as Document;
console.log(".");
});
}
getData(name : String){
console.log("hello name -> " , name)
// document.getElementById("paragraph_content").innerHTML = this.DocumentService.getOneDocument(name)
console.log("Before the subscrie");
this.DocumentService.getOneDocument(name)
.subscribe( (res ) =>{
//I need to change the paragraph content like this
//document.getElementById("paragraph_content").innerHTML = res.toString() Not working
console.log("Within", res);
} )
console.log("After Subscribe ")
}
Document Service
I got the arrays of the url given
getDocuments(){
console.log("Get Documents method");
return this.http.get(this.URL_API );
}
getOneDocument(name: String){
console.log("Get OneDocyment method name given: " , name);
return this.http.get(this.URL_API + `/${name}`)
}
postDocument(){
//left
}
deleteDocument(name:String){
//left
}
Document Component html
<nav>
<ul class="ds-list-unstyled" *ngFor="let document of DocumentService.documents">
<li> {{document}} </li>
</ul>
</nav>
<article>
<h2>Texto en pantalla: </h2>
<p id="paragraph_content">Needs to change with a click
</p>
</article>
And the responde that I got when I click a file is:
Thanks in advance
The XMLHttpRequest property responseType is an enumerated string value specifying the type of data contained in the response. It also lets the author change the response type.
You should set the responseType to text.
Try like this
getOneDocument(name: String){
console.log("Get OneDocyment method name given: " , name);
const requestOptions: Object = {
responseType: 'text'
}
return this.http.get(`${this.URL_API}/${name}`,requestOptions )
}
I think you problem is that you are not specifying that the data is text, that is why is trying to convert to JSON.
Try adding the responseType to the request, something like this,
getOneDocument(name: String){
return this.http.get(`${this.URL_API}/${name}`, {responseType: 'text'})
}

Show the item hit content only when the search box is not empty

I have this in my algolia file for my jekyll site.
<script>
const search = instantsearch({
appId: '{{ site.algolia.application_id }}',
apiKey: '{{ site.algolia.search_only_api_key }}',
indexName: '{{ site.algolia.index_name }}',
searchParameters: {
restrictSearchableAttributes: [
'title',
'content'
],
facetFilters: ['type:post']
},
});
const hitTemplate = function(hit) {
let date = '';
if (hit.date) {
date = moment.unix(hit.date).format('L');
// date = moment.unix(hit.date).format('MMM Do YY');
modifiedDate = moment.unix(hit.last_modified_at).format('MMM Do YY');
}
const url = hit.url;
const title = hit._highlightResult.title.value;
const content = hit._highlightResult.html.value;
return `
<div class="post-list">
<span class="post-date-list-wrap">
<span class="post-date-list">${date}
<span class="post-title"> ${title} </span>
</span>
${content}
</div>
`;
}
const hitTemplateTrans = function(hit) {
let date = '';
if (hit.date) {
date = moment.unix(hit.date).format('MMM DD YYYY');
}
const url = hit.url;
const title = hit._highlightResult.title.value;
const content = hit._highlightResult.html.value;
return `
<div class="post-list">
<span class="post-date-list-wrap">
<span class="post-date-list">${date}
<span class="post-title"> ${title}</span>
</span>
</span>
</div>
`;
}
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-searchbar',
placeholder: 'search notes',
autofocus: true
})
);
search.addWidget(
instantsearch.widgets.hits({
container: '#search-hits',
templates: {
empty: 'No results',
item: hitTemplate
},
})
);
search.start();
</script>
Without typing anything in the search box I have the list of articles
with the excerpt, the short introduction of the article.
That's because I have ${content} to show the highlights when someone
types the search term.
That's fine and everything is working but... I don't want to show the contents of each item when the search box is empty.
If the search box is empty I would like to keep only the title and the date
but if the search box is not empty just show the title/date and the excerpt as it's usual.
It seems like an easy task but I'm stuck right now, I tried removed the content tag and put in the hit transformation function, but it doesn't work.
The instantsearch.js library has a function hook, called searchFunction, you can define when instanciating the library. That is called right before any search is performed. You can use it to check if the current query is empty or not, and adapt your layout based on this knowledge.
Here is a slightly edited script (irrelevant parts removed) that should let you do what you're looking for:
let additionalClass = '';
const search = instantsearch({
[…]
searchFunction: function(helper) {
if (helper.getState().query === '') {
additionalClass = 'post-item__empty-query';
} else {
additionalClass = '';
}
helper.search()
}
});
[…]
const hitTemplate = function(hit) {
return
`<div class="post-item ${additionalClass}">
[…]
</div>`
;
}
.post-item__empty-query .post-snippet {
display: none;
}
What it does is defining a global variable (additionalClass) that will be used in the hit template (added alongside item-post, at the root level).
Right before everysearch, we check if the query is empty. If so, we set additionalClass to item-post__empty_query. We also defined in CSS that when this class is applied, the content should be hidden.
All of that together makes the title + date displayed when no search is performed, and the content displayed only when an actual keyword is searched for.
Hope that helps,

Can a lodash template be used in Node.js to send HTML version of an email?

I am using Node.js to send a confirmation email when a user submits an order. I would like the email to include include all items that the user submits. The number of items will vary with each submission. I'd like the email body to include a table. Can a lodash template be used for this? Or should this be handled differently?
When I used the following code, the resulting email includes what I assume to be uncompiled code.
var tpl = _.template('<% _.forEach(items, function(item) { %><td><%- item %></td><% }); %>');
tpl({ 'items': ['Guitar', 'Harmonica'] });
var data = {
from: 'support#example.com',
to: email,
subject: 'Your Order Confirmation',
html: '<p>Thank you for submitting your order.</p>
<table>
<tr>
<thead>
<tr>
<th><strong>Items</strong></th>'
+ tpl +
// The template should insert each item here
// <td>Guitar</td>
// <td>Harmonica</td>
'</tr>
</thead>
</tr>
</table>'
};
Output in actual email sent:
function (obj) { obj || (obj = {}); var __t, __p = '', __e = _.escape,
__j = Array.prototype.join; function print() { __p +=
__j.call(arguments, '') } with (obj) { _.forEach(items,
function(item) { ; __p += ' ' + __e( item ) + ' '; }); ; } return
__p }
change:
tpl({ 'items': ['Guitar', 'Harmonica'] });
to
var html = tpl({ 'items': ['Guitar', 'Harmonica'] });
and
ng>Items</strong></th>'
+ tpl +
to
ng>Items</strong></th>'
+ html +
if you look at the docs at: https://lodash.com/docs#template
you will see the compiled function returns an output which you need to use.
You instead of using the output, you used the actual function itself.

Resources