Tushar Khatiwada
Tushar Khatiwada

Reputation: 2027

unable to update a mongodb collection from the graphql mutation

I am having trouble solving the following issue. I satrted to develop GraphQL server using NodeJS, Apollo and Mongoose.

Below are some of the sample data from the database:

PrescriptionSetup

{
                "_id": "5ea99ae6fc48d036e083ec20",
                "name": "Calcium",
                "valueTo": -51,
                "valueFrom": -75,
                "treatmentDescription": "Deficiency",
                "recommendation": "<p><strong>Calcium Deficiency</strong></p>\n<p><strong>S &amp; S include: </strong></p>\n<p>Anxiety, Muscle cramps, and spasms, Bruising, Nervousness, Insomnia, Osteoporosis, Tooth decay</p>\n<p><strong>Calcium sources:</strong></p>\n<p>Milk, cheese and other dairy&Acirc;&nbsp;foods. Broccoli, cabbage and okra, Soya beans, Nuts, Flour,&nbsp;Fish</p>",
                "isNormal": false
            },
            {
                "_id": "5ea99ae6fc48d036e083ec21",
                "name": "Calcium",
                "valueTo": 100,
                "valueFrom": 76,
                "treatmentDescription": "High Bio-unavailable",
                "recommendation": "<p><strong>Calcium Excess</strong></p>\n<p><strong>S &amp; S include:</strong></p>\n<p>Arthritis, Gall stones, Constipation, Kidney stones, Depression, Mental, Fatigue.</p>\n<p><strong>Calcium sources:</strong></p>\n<p>Milk, cheese and other dairy&nbsp;foods.Broccoli, cabbage and okra, Soya beans, Nuts, Flour, Fish</p>",
                "isNormal": false
            },
            {
                "_id": "5ea99ae6fc48d036e083ec89",
                "name": "Calcium",
                "valueTo": -26,
                "valueFrom": -50,
                "treatmentDescription": "Border line deficiency",
                "recommendation": "<p><strong>Calcium Borderline Deficiency</strong></p>\n<p><strong>S &amp; S include: </strong></p>\n<p>Fatigue.Weak and brittle fingernails.Poor appetite. Muscle cramps, stiffness, and spasms.</p>\n<p><strong>Calcium sources:</strong></p>\n<p>Milk, cheese and other dairy&Acirc;&nbsp;foods. Broccoli, cabbage and okra, Soya beans.<br /> Nuts. Flour.&nbsp;Fish</p>",
                "isNormal": false
            },
            {
                "_id": "5ea99ae6fc48d036e083ec8a",
                "name": "Calcium",
                "valueTo": -76,
                "valueFrom": -100,
                "treatmentDescription": "insufficiency",
                "recommendation": "<p><strong>Calcium Insufficiency</strong> <br /><strong>S &amp; S include: </strong></p>\n<p>Anxiety, Muscle cramps and spasms, Bruising, Nervousness, Insomnia, Osteoporosis, Tooth decay</p>\n<p><strong>Calcium sources:</strong></p>\n<p>Milk, cheese and other dairy&Acirc;&nbsp;foods.Broccoli, cabbage and okra, Soya beans , Nuts , Flour , Fish</p>",
                "isNormal": false
            },
            {
                "_id": "5ea99ae6fc48d036e083ec22",
                "name": "Magnesium",
                "valueTo": 100,
                "valueFrom": 76,
                "treatmentDescription": "High Bio-unavailable",
                "recommendation": "<p><strong>Magnesium Excess</strong></p>\n<p><strong>S &amp; S include:</strong></p>\n<p>Confusion, Fatigue, Depression, Low blood pressure, Diarrhea, Muscle weakness</p>\n<p><strong>Magnesium sources:</strong></p>\n<p>Spinach, figs, avocado, banana and raspberries. Nuts and seeds. Legumes. Peas, broccoli, cabbage, green beans, artichokes, Seafood</p>",
                "isNormal": false
            },
            {
                "_id": "5ea99ae6fc48d036e083ec53",
                "name": "Magnesium",
                "valueTo": 25,
                "valueFrom": -25,
                "treatmentDescription": "Normal / Ideal zone",
                "recommendation": "",
                "isNormal": true
            },

ParsedPdf

 {
_id: "5eb2da3a4c6ccc6f65d7e621",
"mineralTestReport": 
[
    {
        "name": "Calcium",
        "value": "25",
        "details": null
    },
    {
        "name": "Magnesium",
        "value": "-25",
        "details": null
    },
    {
        "name": "Phosphorus",
        "value": "-71",
        "details": null
    },
    ],
    "ratios": 
    [
        {
            "name": "Ca/Mg",
            "value": "43",
            "details": null
        },
        {
            "name": "Ca/P",
            "value": "100",
            "details": null
        },
        {
            "name": "K/Na",
            "value": "-75",
            "details": null
        },
        {
            "name": "Cu/Zn",
            "value": "-3",
            "details": null
        }
    ]}

What I wanted to do is, take the "name" and "value" from each of the array on the ParsedPdf, check where the "value" lies in between the "valueFrom" and "valueTo" from the PrescriptionSetup and update the "detail" with "description" and "recommendation".

This is what I did. I created a Mutation:

updateParsePdf: authenticated(async (parent, args, context, info) => {
      try {
        const pdf = await ParsePdf.findById(args._id);
        const newReport = await updatedReport(pdf._doc);
        const reportUpdated = await ParsePdf.findByIdAndUpdate(args._id, {
          newReport,
        }).exec();
          return reportUpdated._doc;
      } catch (error) {
        console.log("error: ", error);
        throw new AuthenticationError("Opps! Something went wrong.", error);
      }
    }),

updateReport method

    const updatedReport = async (pdf) => {
    //pdf is the response from the ParsedPdf above
  let updated = {};
  try {
    await Object.keys(pdf).forEach((key) => {
      const field = pdf[key];
      if (Array.isArray(field)) {
        const newRep = field.map(async (f) => {
          const pp = PrescriptionSetup.find({
            name: f.name,
            valueFrom: {
              $lte: f.value,
            },
            valueTo: {
              $gte: f.value,
            },
          })
            .exec()
            .then((p) => {
              return {
                ...f,
                details: {
                  description: p[0].treatmentDescription,
                  recommendation: p[0].recommendation,
                  isNormal: p[0].isNormal,
                },
              };
            })
            .catch((e) => {
              console.log("Error finding setup: ", e);
            });
          return pp;
        });
        updated = { ...updated, [key]: [...newRep] };
      }
    });
    const aa = { ...pdf, ...updated };
    return aa;
  } catch (error) {
    console.log("Error...: ", error);
  }
};

There are lots of Arrays inside the ParsedPdf collection with lots of items in it. I think because of the huge db queries, I could not make it work. What is the best approach to solve this.

Thanks for the help

Upvotes: 1

Views: 405

Answers (1)

thammada.ts
thammada.ts

Reputation: 5245

I'll suggest an approach with the least code change.

  1. const pp = PrescriptionSetup.find here pp is a Promise, so newRep will be array of Promises

    instead of [...newRep] use [...await Promise.all(newRep)]

  2. await Object.keys(pdf).forEach((key) => ...) here .forEach doesn't return anything, actually you don't have to await, but we just aded an async logic in (1.) so we have to handle that

    change to await Promise.map(Object.keys(pdf), async (key) => ...) if you use bluebird, else use something equivalent with Promise.map

Upvotes: 1

Related Questions