0
\$\begingroup\$

Following task:

Customer-data, given in a JSON-file, have to be completed with additional address-data. Given in a second JSON-file.

Then these data-stock has to be saved into a MongoDB-database.

Schema of the customer-JSON:

[
    {
      "id": "1",
      "first_name": "Ario",
      "last_name": "Noteyoung",
      "email": "anoteyoung0@nhs.uk",
      "gender": "Male",
      "ip_address": "99.5.160.227",
      "ssn": "509-86-9654",
      "credit_card": "5602256742685208",
      "bitcoin": "179BsXQkUuC6NKYNsQkdmKQKbMBPmJtEHB",
      "street_address": "0227 Kropf Court"
    },
    {
      "id": "2",
      "first_name": "Minni",
      "last_name": "Endon",
      "email": "mendon1@netvibes.com",
      "gender": "Female",
      "ip_address": "213.62.229.103",
      "ssn": "765-11-9543",
      "credit_card": "67613037902735554",
      "bitcoin": "135wbMcR98R6hqqWgEJXHZHcanQKGRPwE1",
      "street_address": "90 Sutteridge Way"
    },
... 
]

Schema of the addresses-JSON:

[
  {
    "country": "United States",
    "city": "New Orleans",
    "state": "Louisiana",
    "phone": "504-981-8641"
  },
  {
    "country": "United States",
    "city": "New York City",
    "state": "New York",
    "phone": "212-312-1945"
  },
...
]

Desired result:

[
  {
    "_id" : ObjectId("5b3f16f5743a6704739bf436"),
    "id" : "1",
    "first_name" : "Ario",
    "last_name" : "Noteyoung",
    "email" : "anoteyoung0@nhs.uk",
    "gender" : "Male",
    "ip_address" : "99.5.160.227",
    "ssn" : "509-86-9654",
    "credit_card" : "5602256742685208",
    "bitcoin" : "179BsXQkUuC6NKYNsQkdmKQKbMBPmJtEHB",
    "street_address" : "0227 Kropf Court",
    "country" : "United States",
    "city" : "New Orleans",
    "state" : "Louisiana",
    "phone" : "504-981-8641"
  },
  ...
]

My solution:

const mongodb = require("mongodb");

const filePathCustomer = "./customers.json";
const filePathAddresses = "./addresses.json";

const MongoClient = mongodb.MongoClient;

completeCustomers = (filePathCustomers, filePathAddresses) => {
  const customers = require(filePathCustomers);
  const addresses = require(filePathAddresses);

  return (updatedCustomers = customers.map((customer, index) => {
    const updatedCustomer = Object.assign(customer, addresses[index]);

    return updatedCustomer;
  }));
};

MongoClient.connect(
  "mongodb://localhost:27017/bitcoinExchange",
  (error, client) => {
    if (error) {
      throw new Error("Connecting to MongoDb has failed.");
    }

    const db = client.db();

    let execCompleteCustomer = new Promise(resolve => {
      resolve(completeCustomers(filePathCustomer, filePathAddresses));
    });

    execCompleteCustomer
      .then(customer => {
        db.collection("customers").insertMany(customer, (error, result) => {
          if (error) {
            db.close();
            throw new Error("Writing to database has failed");
          }
          console.log(
            "Count of customer documents inserted:",
            result.insertedCount
          );

          return true;
        });
      })
      .then(result => {
        if (result) db.close();
      })
      .catch(() => {
        db.close();
        throw new Error("The merging of the customer-data has failed.");
      });
  }
);

What would you have done different and why?

Is my error-handling done in a good way and fashion? How could it be improved?

What bothers me a bit are this multiple occurences of db.close().

Is there a way in Node to avoid these redundancy?

Something like finally in Java.

\$\endgroup\$
  • \$\begingroup\$ How do you know which address to couple with which customer? They don't share an identifier and relying on the order in a JSON smells like a bad idea. \$\endgroup\$ – Mast Jul 6 '18 at 8:22
  • \$\begingroup\$ It's exactly the same amount of objects in addresses then in customer. The element n in customer maps to the element n in addresses. E.g.: customer[3] maps to addresses[3] and so on ... \$\endgroup\$ – michael.zech Jul 6 '18 at 8:26
1
\$\begingroup\$

Just a few things

  1. To start out, the return statement in your function completeCustomers should/could be changed.

The way the function is defined should also be changed. But we'll get to that in a second.

return (updatedCustomers = customers.map((customer, index) => {
  const updatedCustomer = Object.assign(customer, addresses[index]);

  return updatedCustomer;
}));

I would replace with:

return (updatedCustomers = customers.map((customer, index) => ({
  ...customer,
  ...addresses[index]
})))

Note, you don't have to make it take up multiple lines if you don't want.

  1. Use const when you don't modify a variable, or arrow function

This means that the two functions below need to change:

completeCustomers = (filePathCustomers, filePathAddresses) => {

Would become:

const completeCustomers = (filePathCustomers, filePathAddresses) => {

let execCompleteCustomer = new Promise(resolve => {

And this would become:

const execCompleteCustomer = new Promise(resolve => {

That's all I have for now, but I'm not getting what part you are saying is redundant. And I think you handled the errors well.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.