2

I'm trying to figure out how to get value from xml file and output that value to console.

const path = require('path');
const fs = require('fs');
const parseString = require('xml2js').parseString;

const sourceFile = path.join(__dirname, 'books.xml');

const document = (sourceFile, callback) => {
  fs.readFile(sourceFile, { encoding: 'utf-8' }, function (err, data) {
    if (err) {
      return err;
    }

    parseString(data, (err, result) => {
      result.catalog.book.forEach(users => {
        callback(users.email);
      });
    });
  });
};

console.log(document(sourceFile, data => data));

The xml itself is very simple:

<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <email>test@test.com</email>
   </book>
</catalog>

But what I am getting from the function is undefined. Why does it happen?

Update: I'm trying to send returned value to nodemailer

transporter.sendMail({ from: 'mail@mail.com', to: document(sourceFile, (data) => data), subject: 'Message', text: 'I hope this message gets sent!', }, (err, info) => { if (err) { console.log('error!'); console.log(err.message); } else { console.log('sucess!'); console.log(info.messageId); console.log(info.response); }

but I get an error: 'Missing required header 'To'.'

1 Answers1

1

You are not printing value of data, instead printing returned value of document function (Which doesn't return anything, thus undefined).

I have modified the code, so now it will work as you desired,

const path = require('path');
const fs = require('fs');
const parseString = require('xml2js').parseString;

const sourceFile = path.join(__dirname, 'books.xml');

const document = (sourceFile, callback) => {
  fs.readFile(sourceFile, { encoding: 'utf-8' }, function (err, data) {
    if (err) {
      return err;
    }

    parseString(data, (err, result) => {
      result.catalog.book.forEach(users => {
        callback(users.email);
      });
    });
  });
};

document(sourceFile, data => console.log(data));

Update: As per OP's comment,

const path = require('path');
const fs = require('fs');
const parseString = require('xml2js').parseString;

const sourceFile = path.join(__dirname, 'books.xml');

const document = (sourceFile, callback) => {
  fs.readFile(sourceFile, { encoding: 'utf-8' }, function (err, data) {
    if (err) {
      return err;
    }

    parseString(data, (err, result) => {
      result.catalog.book.forEach(users => {
        callback(users.email);
      });
    });
  });
};

document(sourceFile, data => {
  transporter.sendMail({ from: 'mail@mail.com', to: data, subject: 'Message', text: 'I hope this message gets sent!', }, (err, info) => {
    if (err) {
      console.log('error!');
      console.log(err.message);
    } else {
      console.log('sucess!');
      console.log(info.messageId);
      console.log(info.response);
    }
  });
});
Gaurav Gandhi
  • 3,041
  • 2
  • 27
  • 40
  • I'm trying to send returned value to nodemailer `transporter.sendMail({ from: 'mail@mail.com', to: document(sourceFile, (data) => data), subject: 'Message', text: 'I hope this message gets sent!', }, (err, info) => { if (err) { console.log('error!'); console.log(err.message); } else { console.log('sucess!'); console.log(info.messageId); console.log(info.response); } ` but this is the error I'm geting intead: 'Missing required header 'To'.' – Karolis Arbačiauskas Apr 08 '17 at 14:19
  • @KarolisArbačiauskas, please add an update to the question for same, will update my answer. So question answer stay in sync. – Gaurav Gandhi Apr 08 '17 at 14:40
  • @KarolisArbačiauskas I have added update patch to answer. – Gaurav Gandhi Apr 08 '17 at 14:43
  • Thank you! working like a charm. Could you explain, please, why do I need to move sendmail function to callback? – Karolis Arbačiauskas Apr 08 '17 at 14:47
  • You have to understand the working of `callbacks`, `async` and similar stuff. You were doing several mistakes. First, you were calling a function in a manner that it will return value, but the value is coming with callback as it;s async operation. Second, You were not waiting for the callback to fire to further execution. – Gaurav Gandhi Apr 08 '17 at 14:50
  • Read this article, https://blog.risingstack.com/node-hero-async-programming-in-node-js/ – Gaurav Gandhi Apr 08 '17 at 14:54