0

So, I used express-generator to create an app skeleton. The Bin/www server configuration is new to me. In my app I want to access the test.json file in the data dir. Now, I get an error telling me the dir does not exist. I noticed something different from my other apps. I found that process.mainModule.filename is including the bin dir. I checked the base name and it spit out "www". Weird. Now I am new at this in the sense that I haven't ever had to trouble shoot this before. I found out some interesting things.

First here is the error message:

```{
  [Error: ENOENT: no such file or directory, open '/Users/macbook/Documents/web-development/weather-app/bin/data/test']
  errno: -2,
    code: 'ENOENT',
    syscall: 'open',
    path:
    '/Users/macbook/Documents/web-development/weather-app/bin/data/test'
}```
  1.  const testPath = path.join(
        path.dirname(maimMod),
        'data',
        'test'
    ); // /Users/macbook/Documents/web-development/weather-app/data/test```
    
    
  2.     path.dirname(process.mainModule.filename),
        'data',
        // 'city_list.json',
        'test'
    ); // /Users/macbook/Documents/web-development/weather-app/bin/data/test```
    
    

mainMode === p. // false -- What is going on here? Why is /bin/ excluded from the path in testPath?

Now when I try to read the test.json file I get the same result either way. I can't figure out what I am doing wrong.

Here is all the code -- I removed my api key:

const axios = require('axios');
const fs = require('fs');
const path = require('path');

const p = path.join(
  path.dirname(process.mainModule.filename),
  'data',
  // 'city_list.json',
  'test'
);

const mainMod = path.dirname(process.mainModule.filename);
const testPath = path.join(
  path.dirname(mainMod),
  'data',
  // 'city_list.json',
  'test'
);

console.log("p: ", p);
console.log("mainMod: ", path.dirname(mainMod));
let result = p === testPath;
console.log(result);

const getCityData = cb => {
  fs.readFile(p, (err, fileContent) => {
    if (err) {
      console.log(err);
      cb([]);
    } else {
      // console.log(JSON.parse(fileContent));
      cb(JSON.parse(fileContent));
    }
  });
}

const getCurrentWeather = cb => {
  const key = ;
  const cityID = '5586437';
  axios.get(`http://api.openweathermap.org/data/2.5/weather?id=${cityID}&appid=${key}&units=imperial`)
    .then(function(response) {
      cb(response);
      // console.log(response);
    })
    .catch(function(error) {
      console.log(error)
    });
}

module.exports = class WeatherData {
  // Fetches current weather
  static fetchData(cb) {
    getCurrentWeather(cb);
  }

  // Fetch city, state, country for input lookup

  static locateCityState(cb) {
    getCityData(cb);
  }
}
Christian
  • 51
  • 7

2 Answers2

0

For the benefit of other readers, the default project file structure for express-generator looks like this:

|-- bin
|   |-- www
|-- node_modules
|-- public
|-- routes
|-- views
|-- app.js
|-- package.json

I found that process.mainModule.filename is including the bin dir. I checked the base name and it spit out "www". Weird.

I am assuming you are running the start script that comes with an express-generator project (npm start or equivalent). If you look in package.json, you will see this runs node ./bin/www which makes bin/www your entry point (main module):

  "scripts": {
    "start": "node ./bin/www"
  },

So, process.mainModule.filename === '/Users/macbook/Documents/web-development/weather-app/bin/www'.

mainMode === p. // false -- What is going on here? Why is /bin/ excluded from the path in testPath?

bin is excluded from testPath because you called path.dirname twice: once on process.mainModule.filename when assigning a value to the mainMod variable, which drops www (line 12 in your snippet) - and again on mainMod when assigning a value to testPath, which drops bin (line 14).

Hopefully this helps.

Side note: determining the "root" directory can be brittle and unreliable. Check out this answer for options and their trade-offs.

wKovacs64
  • 21
  • 1
  • 3
0

Saving process.mainModule to a variable then passing it to path.dirname() worked. And, I would have figure it out much sooner if I hadn't made a silly typo mistake. Had I not made that little typo I don't think I would have learned as much about how this system works. So, that's the upside. I should open a lemonade factory.

Christian
  • 51
  • 7