sails.js view does not load - node.js

I made a controller which get data from a rest api and
serializes them to .xls file.
In my web view I have a button with "Create xls data" which call my controller.
Then my controller sierialises and reload this view with the xls download link and a "Download data" button.
My view import_export_data_page.ejs:
At start button "Create xls data" is displayed.
<%
if(typeof link == 'undefined'){
%>
<button type="button" class="btn btn-primary" id="button_get_xls_file">Create xls data</button>
<%
}else {
%>
<button type="button" class="btn btn-primary"></button>
<%
}
%>
<script type="text/javascript">
$('#button_get_xls_file').click(function(){
var projectName = getCurrentServiceName(currentService);
$.get( "/api/export_xls_data", { url : currentService, projectname : projectName} ).done(function( data ) {
});
});
</script>
In my controller :
exportXLS : function(req,res)
{
var request = require('request');
var categories;
//get informations
request(url + "/places", function (error, response, body) {
categories = JSON.parse(body);
/*
* Parsing tacks 3 seconds max
*/
//if file exists delete and create file
fs.exists(fileName, function (exists) {
if(exists){
fs.unlinkSync(fileName);
}
fs.writeFile(fileName, xls, 'binary',function(err){
if(err){
console.log(err);
res.status(500);
return res.send("");
}else{
var downloadLink = req.headers.host+'/xls/'+currentProject.split(' ').join('')+'_data.xls';
console.log(downloadLink);
return res.view('import_export_data_page',{link : downloadLink});
});
});
}
}
My file is created. My link works but my view is not reloaded.

Your view is not reloaded because your making an AJAX call. There is nothing in your code to tell the page to reload the view.
I think you want to change this:
$.get( "/api/export_xls_data", { url : currentService, projectname : projectName} ).done(function( data ) {});
to:
window.location.href = '/api/export_xls_data?url=' + currentService + '&projectname=' + projectName

Related

How do I have a variable available to display on my success page, after adding items to a database via a /POST route?

I would like to display the doc.id variable of a successful /POST of data to a route, on the success page that the user will be redirected to afterward. I'm trying to work out how to carry the variable teamId through to the Handlebar template page success.hbs
I've tried making it a variable, and setting up a Handlebar helper to display it, but nothing is working.
/POST route redirecting to success.hbs:
app.post('/create', (req, res) => {
var players = [];
var playerObj = {};
for (let i = 1; i < 21; i++) {
var playerObj = { playerName: req.body[`player${i}Name`], playerNumber: req.body[`player${i}Number`], playerPosition: req.body[`player${i}Position`] };
if (req.body["player" + i + "Name"] === '') {
console.log("Empty player name detected, disregarding");
} else {
players.push(playerObj);
}
}
var newTeam = new Team({
// WEB SETUP BELOW
"team.teamRoster.teamCoach": req.body.coachName,
"team.shortTeamName": req.body.teamShortName,
"team.teamName": req.body.teamName,
"team.teamRoster.players": players
});
newTeam.save().then((doc) => {
var teamId = doc.id;
console.log(teamId);
res.render('success.hbs');
console.log("Team Added");
}, (e) => {
res.status(400).send(e);
});
});
/views/success.hbs
<div class="container-fluid" id="body">
<div class="container" id="page-header">
<h1><span id="headline">Team Added Succesfully</span></h1>
<hr>
<h3><span id="subheadline">Input the following address as a JSON Data Source within vMix.</span></h3>
<span id="content">
<div class="row">
<div class="container col-md-12">
{{{teamId}}}
</div>
</div>
</span>
</div>
<hr>
</div>
I'd like a Handlebar helper to get the doc.id value of the /POST request, and store it as teamId to display on the success page. It's finding nothing at the moment.
Any help is appreciated.
Node.js can pass variables to the handlebars-view like this:
newTeam.save().then((doc) => {
var teamId = doc.id;
console.log(teamId);
res.render('success.hbs', {
teamId
});
console.log("Team Added");
}, (e) => {
res.status(400).send(e);
});

Save file to mongodb using angular and Nodejs

I am trying to upload an image to mongodb using angular and nodejs. The code is below. I got the backend working but the problem is with the html input i get 'C:fakepath/file.xyz'. I was looking online and saw that there is not a way to get the relative path of the file. Can someone please tell me how i can change my front end code to get and send the file path to the backend to then save. I read that the browser doesnt allow relative path of the file but then how can I upload. Thanks!
The nodejs image save method is:
async function SaveImage(userParam) {
const entry = new imageEntries(userParam);
entry.image.data = fs.readFileSync(userParam.imagePath);
entry.image.contentType = 'image/png';
await entry.save();
}
The html code is:
<div class="upload-btn-wrapper">
<button class="btn">Upload a file</button>
<input type="file" name="myfile" id="myFile" />
</div>
What I pass as the path in the backend is:
ImageJournal.imagePath = (<HTMLInputElement>document.getElementById('myFile')).value;
but with the code above i get the following error:
ENOENT: no such file or directory, open 'C:\fakepath\chapter9problemsandanswers.doc'
Ok here it is:
HTML:
<div class="form-group">
<label for="pdf">PDF</label>
<input type="file" id="pdf" (change)="onFileChange($event)" #fileInput>
<button type="button" class="btn btn-sm btn-default" (click)="clearFile()">clear file</button>
</div>
TS:
import { Component, OnInit, ElementRef, ViewChild } from '#angular/core';
#ViewChild('fileInput') fileInput: ElementRef;
public image;
onFileChange(event) {
let reader = new FileReader();
if(event.target.files && event.target.files.length > 0) {
let file = event.target.files[0];
reader.readAsDataURL(file);
let value = <String>reader.result;
reader.onload = () => {
this.image = {
filename: file.name,
filetype: file.type,
value: value.split(',')[1]
};
};
}
}
Then send the image with http post with a service.
On the server:
// send file
app.post('/api/sendFile', function (req, res) {
File.create({
filename: req.body.filename,
filetype: req.body.filetype,
value: req.body.value
}, function (err, file) {
if (err)
res.send(err);
else {
const response = {
name: file.filename
}
res.send(response);
}
});
});
This is written with mongoDb and mongoose and I have a model named File.
This is all it need to save it.

How can I pass id to the router delete method?

I have a list of data shown with a delete button as below.
<ul class="quotes">
<% for(var i=0; i<quotes.length; i++) {%>
<li class="quote" data-id= "<%= quotes[i]._id %>">
<span><%= quotes[i].name %></span> -
<span><b><%= quotes[i].price %></b></span>
<button class="delete-todo">×</button>
</li>
<% } %>
</ul>
From jQuery I am passing the id to be deleted as follow:
$('.delete-todo').on('click', function(e){
e.preventDefault();
var id = $(this).parent().data('id');
$.post('/products',{'id':id},function(data){
},'json');
});
I have a product.router.js as follows:
router.delete(':/id', product_controller.product_delete);
I am confused about how to call this delete of router and pass the id to this router method.
In NodeJS
router.delete('/products/:id', product_controller.product_delete);
and you will get in params( req.params.id) in product_controller.product_delete function
and in JQuery
$('.delete-todo').on('click', function(e){
e.preventDefault();
var id = $(this).parent().data('id');
$.ajax({
url: '/products/'+ id,
type: 'DELETE',
success: function(data) {
// your success response data here in data variable
console.log('result ', data);
}
});
});
Check this
Express JS
router.delete('/:id', product_controller.product_delete);
// If you are using router in `app.use('products', router)`
OR
router.delete('products/:id', product_controller.product_delete);
Ajax Call
$.ajax({
url: '/products/'+ id,
type: 'DELETE',
success: callback
});

Template actual data context

I have troubles with data context;
Here is my code (unfortunatly, meteorpad is broken)
router.js(I use iron:router)
Router.configure({
layoutTemplate: 'layout'
});
Router.route('home',{
path: '/',
action: function(){
this.redirect('sections', {page: 0});
}
});
Router.route('sections', {
path: '/sections/:page',
data: function(){
var data = {};
data.params = {};
data.params.page = this.params.page?this.params.page:0;
return data;
}
});
template.html
<template name="layout">
{{>yield}}
</template>
<template name="sections">
Page: {{params.page}}
<br>
Page 0
Page 1
Page 2
<br>
<button>what page?</button>
</template>
template.js
Template.sections.onRendered(function(){
let scope = this;
$("button").on("click", function(){
alert("page: " + scope.data.params.page);
});
});
When I click button, button-handler has the scope, which had the template, when rendered, but not actual in this moment;
thanks to #user3374348
method Blaze.getData(scope.view) returns actual data context.
template.js
Template.sections.onRendered(function(){
let scope = this;
$("button").on("click", function(){
alert("page: " + Blaze.getData(scope.view).params.page);
});
});

post input type file to server node.js from angular service call

I have simple multipart formdata
<form action="/upload" enctype="multipart/form-data" method="post">
<span class="btn btn-file">
<input type="file" name="file" ng-model="file"/>
<span class="btn btn-primary" ng-click="upload()">Upload</span>
</span>
</form>
What I want to do it, post all the information related to file to the server written in node.js
server.js This is file upload handler written in node. Formidable expects all parameters of a file.
upload: function uploadfn (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
// `file` is the name of the <input> field of type `file`
var old_path = files.file.path,
file_size = files.file.size,
file_ext = files.file.name.split('.').pop(),
index = old_path.lastIndexOf('/') + 1,
file_name = old_path.substr(index),
new_path = path.join(process.env.PWD, '/uploads/', file_name + '.' + file_ext);
fs.readFile(old_path, function(err, data) {
fs.writeFile(new_path, data, function(err) {
fs.unlink(old_path, function(err) {
if (err) {
res.status(500);
res.json({'success': false});
} else {
res.status(200);
res.json({'success': true});
}
});
});
});
});
}
The things I'm stuck at is, I have service call ready in angular as follows:
service.factory('FileUpload', function ($resource) {
return $resource('/upload', {}, {
post: {method: 'POST'}
});
});
This call hits the backend from angular controller as follows
$scope.upload = function(){
console.log($scope.file);
FileUpload.post(function(){
});
}
I'm not sure how to post the file submit so that node can catch it. Also $scope.file is undefined.
Please help me solve this.
There's a good directive for file upload for angularjs, try to use it
https://github.com/danialfarid/angular-file-upload

Resources