Trouble writing a file with CronJob in Heroku using writeFileSync() - node.js

I am trying to repeatedly update a file using a cronjob. Eventually, this is going to be more complicated but for now I'm trying to figure out my current problem. I know the code below is somewhat over-complicated because I preserved the basic structure while trying to problem solve. Here is the server file:
// server.js
var express = require('express');
var port = process.env.PORT || 8080;
var http = require('http');
var fs = require("fs");
var curtainup = require('./diagnoseleak.js');
var url = require("url" );
var app = express();
// launch ======================================================================
app.listen(port);
//run the CronJob
var CronJob = require('cron').CronJob;
new CronJob('0 * * * * *', function() {
console.log("running");
var date = new Date();
console.log("Ran at: "+date.getHours()+":"+date.getMinutes());
curtainup.doitnow();
} , null, true, 'America/New_York');
And here is the file referenced called diagnoseleak.js:
var fs = require("fs");
var mostRecentLocation = "./config/pullfiles/mostRecent55.txt";
module.exports = {
doitnow: function(){
var writethefile = function(){
fs.writeFileSync(mostRecentLocation, "A file called mostRecent55 should be create with this text", { flag: 'w' });
console.log("This should write to the console");
}
writethefile();
}
}
From the directory that houses the server file, I type the following into cmd:
git add .
git commit -m "adding files"
git push heroku master
heroku run bash
Then into the bash window I type:
cd config/pullfiles
ls -l
AND...no file called mostRecent55.txt appears. Am I looking in the wrong place? Eventually I want to be able to update a file, but I have a feeling I'm either looking in the wrong place for this mostRecet55.txt file or going about the process of writing it incorrectly.

heroku doesn't let you write files onto the filesystem where your app is stored. You would need to use an add-on, database or external service of some kind. The only exception seems to be /tmp which is only temporary storage

Related

shell.cd "No directory name could be guessed"

I want to use a nodejs script to clone and do some other ops at a given repo. However, whenever I do shell.cd(path) as seen below it crashes with the
"No directory name could be guessed"
Here's the script
const nodeCron = require("node-cron");
const shell = require('shelljs');
const path = './';
require('dotenv').config();
const start = Date.now();
async function GitOps(){
console.log("Running scheduled job", start);
shell.cd(path);
shell.exec('git clone -b dev https://',process.env.USERNAME,':',process.env.PASSWORD,'#github.com:Jamesmosley/xyz-git-ops.git');
return console.log("Job finished");
}
const job = nodeCron.schedule("* * * * *", GitOps);
I mean to clone right into my working directory. I tried some stuff like adding 'pwd' at the const path and adding the root folder at the end of the clone command, to no avail:
shell.exec('git clone -b dev https://',process.env.USERNAME,':',process.env.PASSWORD,'#github.com:Jamesmosley/xyz-git-ops.git' ./);
After all, the only thing missing was literaly pasting my absolute path into the path variable:
const path = '/Users/Jamesmosley/Documents/Git Ops Cron/repos';
then doing shell.cd(path)

I get require is not defined error if I call it from external files

Hi,
I made an app for node.js so my app.js looks like this:
global.fs = require("fs");
global.vm = require('vm');
var includefile = function(path) {
var code = fs.readFileSync(path);
vm.runInThisContext(code, path);
}.bind(this);
includefile("variables.js");
as for variables.js I have this:
global.app = require("express")();
but when I start the app I get this error:
require is not defined at variables.js
why is it that requires loads fine if executed from app.js but not from an external file?
Thank you.
I'm a little confused, is variables.js just another source file in your project? All you should need to do is require the file in like you've done at the top. As an example for variables.js:
const Variables = {
fs: "some_value"
};
module.exports = Variables;
And for app.js
const { Variables } = require("./variables.js");
const fs = Variables.fs;
Executing console.log(fs); in app.js will print "some_value". Same can be done with functions.
If variables.js is part of your project code, you should use the answer of M. Gercz.
If it's not part of your project code and you want to get some information from it, you could use a json file:
app.js
const variables = require('variables.json');
console.log(variables.whatever);
variables.json
{ whatever: "valuable information" }
If it's not certain, that variables.json is preset, you can do a check using fs.existsSync;
Notice: As jfriend00 commented, using global is not recommended.

Generating a json for a icon cheatsheet

I'm trying to generate a json file containing the filenames of all the files in a certain directory. I need this to create a cheatsheet for icons.
Currently I'm trying to run a script locally via terminal, to generate the json. That json will be the input for a react component that will display icons. That component works, the create json script doesn't.
Code for generating the json
const fs = require('fs');
const path = require('path');
/**
* Create JSON file
*/
const CreateJson = () => {
const files = [];
const dir = '../icons';
fs.readdirSync(dir).forEach(filename => {
const name = path.parse(filename);
const filepath = path.resolve(dir, filename);
const stat = fs.statSync(filepath);
const isFile = stat.isFile();
if (isFile) files.push({ name });
});
const data = JSON.stringify(files, null, 2);
fs.writeFileSync('../Icons.json', data);
};
module.exports = CreateJson;
I run it in terminal using
"create:json": "NODE_ENV=build node ./scripts/CreateJson.js"
I expect a json file to be created/overridden. But terminal returns:
$ NODE_ENV=build node ./scripts/CreateJson.js
✨ Done in 0.16s.
Any pointers?
You are creating a function CreateJson and exporting it, but you are actually never calling it.
You can get rid of the module.exports and replace it with CreateJson().
When you'll execute the file with node, it will see the function declaration, and a call to it, whereas with your current code there is no call.

How to create application level variable in node.js

In my project I have running more than 100 cron jon using npm cron. My problem is I need to stop any cron job at run time.
my code is
in app.js file
var cronJobRunner =require('cronJobHandle.js');
global.jobManager = {};
cronJobRunner.startServiceFromCronJobManager("service 1")
in cronJobHandle.js
var CronJob = require('cron').CronJob;
module.exports = {
startServiceFromCronJobManager: function (scheduleServiceName) {
var serviceList =['service1','service2','service3','service4']
serviceList.forEach(function(service){
var job = new CronJob('* * * * * *', function(){
console.log("Service running");
}, function () {
// This function is executed when the job stops
},
true /* Start the job right now */,
timeZone /* Time zone of this job. */
);
global.jobManager.service = job;
});
},
stopServiceFromCronJobManager: function (scheduleServiceName) {
console.log(global.jobManager);
global.jobManager[scheduleServiceName].stop();
}
};
router.js
var cronJobRunner =require('cronJobHandle.js');
app.route('/stopservice',function(req,res){
cronJobRunner.stopServiceFromCronJobManager("service1");
}
When I call http://localhost:9999/stopservice
I am getting undefine in console.log(global.jobManager);
Please help me how to maintain cron jobManager variable comman for all server side js files
It is global but there's two bugs in your code.
1) you're calling the property called "service" instead of the one whose name is in service.
Change
global.jobManager.service = job;
to
global.jobManager[service] = job;
2) you're pottentially using global.jobManager in cronJobHandle.js before to declare it in app.js
There's a better solution. you don't need and should use global. Just declare a standard variable in cronJobHandle.js instead (so that it isn't accessed by other modules):
var jobManager = {};
...
jobManager[service] = job;
...
jobManager[scheduleServiceName].stop();

Piping files to a connect server with gulp

This is a speculative question about delivering files to a server. I have recently moved from using grunt to gulp. I like the fact that I do not have to have temporary files littering my directory and requiring a larger .gitignore file.
Is it possible to run file processing and them pipe them directly to a server. All the examples I have found so far pipe to a destination directory which is then served. What I would like to create is something very similar to the following
var gulp = require('gulp');
var browserify = require('gulp-browserify');
var connect = require('gulp-connect');
var merge = require('merge-stream');
gulp.task('test', function () {
var js = gulp.src('test/index.js')
.pipe(browserify());
var html = gulp.src('test/index.html');
merge(html, js)
.pipe(connect.server({
port: 8080
}));
gulp.watch('test/*', function () {
console.log('boo');
});
});

Resources