1

Here is the function when I save the data on a click on save button, it collect all the data from the form and set it in json and save.

function traverseData(data, obj, newValue)
  {
      for (var k in data)
      {
          if (data.hasOwnProperty(k) && typeof data[k] == "object") {
              data[k] = traverseData(data[k], obj, newValue);
              console.log("k="+k+", obj="+obj);
          } else if (k == obj) {
            data[k] = newValue;
          }
      }
      return data
  }

This is the json in which i am trying to add the property

{
    "invoice":
    {
        "ocrData":
        {
            "invoiceNumber":"FM334J",
            "paymentDate":"Feb 24 , 2022",
            "sellerName":"Q FOTURE LTD",
            "sellerPhone":"+ 004154",
            "sellerAddress":"ROOM 1010",
            "sellerEmail":"",
            "sellerFax":"0088960",
            "sellerWebsite":"",
            "bankName":"S P DEVELOPMENT BANK",
            "bankAccountNumber":"00819",
            "bankAddress":"bank address",
            "ibanCode":"",
            "swiftCode":"SP0",
            "paymentCurrency":"USD",
            "paymentAmount":"60.00",
            "buyerName":"C TRADING",
            "buyerAddress":"44 AVE",
            "buyerWebsite":"website",
            "buyerAccountNumber":"0000819",
            "portOfLoading":"Casmora",
            "shipmentDate":"",
            "destination":"DAKAR",
            "currencySettlement":"XOF"
        },
        "products":
        [
            {
                "productDescription":"1 * 25KG BAG , 2FCL"
            }
        ],
        "results":
        [
            {
                "line":
                [
                    {
                        "field":"seller_phone",
                        "fieldValue":"+ 008154"
                    },
                    {
                        "field":"invoice_number",
                        "fieldValue":"FM334J"
                    },
                    {
                        "field":"buyer_name",
                        "fieldValue":"C TRADING"
                    },
                    {
                        "field":"seller_name",
                        "fieldValue":"Q FOTURE LTD"
                    },
                    {
                        "field":"seller_name",
                        "fieldValue":"Q FOTURE LTD"
                    },
                    {
                        "field":"seller_fax_number",
                        "fieldValue":"008960"
                    },
                    {
                        "field":"invoice_date",
                        "fieldValue":"Feb 24 , 2022"
                    },
                    {
                        "field":"buyer_address",
                        "fieldValue":"44 AVE"
                    },
                    {
                        "field":"seller_address",
                        "fieldValue":"ROOM 1010"
                    },
                    {
                        "field":"seller_address",
                        "fieldValue":"NO.I, DAO"
                    },
                    {
                        "field":"currency",
                        "fieldValue":"USD"
                    },
                    {
                        "field":"bank_account_number",
                        "fieldValue":"6000819"
                    },
                    {
                        "field":"seller_website",
                        "fieldValue":"www.fotoup.com"
                    },
                    {
                        "field":"invoice_amount",
                        "fieldValue":"60000"
                    },
                    {
                        "field":"bank_name",
                        "fieldValue":"SHA DEVELOPMENT BANK"
                    },
                    {
                        "field":"table",
                        "fieldValue":"table"
                    }
                ],
                "tableItem":
                [
                    {
                        "tableItem":"Description",
                        "tableItemValue":"1 * 25KG BAG , 2FCL"
                    }
                ]
            }
        ]
    }
}

Now this json doesn't contains the "paymentTerms" property to ocr data. I am trying to add that after "destination", I really appreciate if anyone can help.

  • 2
    What's with the `else` floating in the middle of nowhere? (Well...just after `q++`) This is not valid JavaScript. – Wyck Sep 08 '22 at 12:35
  • 1
    tNV is undefined it seems – Lk77 Sep 08 '22 at 12:35
  • where is tNV data coming from, could you share the logic around it. – kavigun Sep 08 '22 at 12:37
  • @KooiInc, can you suggest how can i do that? – Kode Lerner Sep 08 '22 at 12:42
  • @kavigun, its declared on the top of the file. – Kode Lerner Sep 08 '22 at 12:43
  • @Lk77, tNV is declared on top. – Kode Lerner Sep 08 '22 at 12:44
  • @Wyck, i just missed when i pasted it, its removed. – Kode Lerner Sep 08 '22 at 12:44
  • That is an issue, you defined tNV as a string. That means you are trying to add a JSON object to a string. You need to parse your string data to JSON object using JSON.parse() before dealing with it as an object. You also need to correct your if else condition in the traverseData() method. – kavigun Sep 08 '22 at 12:49
  • Are you aware that the indentation of your code does not correspond to the structure of your loop? Now your indentation has become inconsistent after `q++` and the `if` is **not** in the loop. – Wyck Sep 08 '22 at 12:50
  • @Wyck, yes i am aware of it, and that's because i just removed other codes to make it simple and to the point with the problem. – Kode Lerner Sep 08 '22 at 13:08
  • @kavigun, can you please tell me how to correct the if else in traverseData() method? – Kode Lerner Sep 08 '22 at 13:09
  • The indentation problem is not simpler, it's highly **distracting**. Such inconsistencies are usually evidence of carelessness, typo errors or misunderstanding of the situation. In your case it appears to be a bit of laziness in preparing a minimal example. I think you should put as much effort if not more into writing your question as you expect people to put into answering it. – Wyck Sep 08 '22 at 13:13
  • 1
    @Wyck, i tried to improve my question, i hope this will now not misunderstanding. – Kode Lerner Sep 08 '22 at 21:36
  • Question asking tips: Your question should include the details of the call that you made to `traverseData` by showing the arguments that you passed it. And then you should explain the expected vs actual results. Even better would be if you put it into a runnable stack snippet so that the code in the question itself demonstrates the problem entirely. Although I think traktor's excellent answer has already managed to see through the fog and give you what you needed. – Wyck Sep 09 '22 at 14:33
  • @Wyck, thanks, i will keep that in mind next time i ask any question. – Kode Lerner Sep 12 '22 at 16:14

1 Answers1

2

Assumption: code has parsed JSON text string representations of object data before accessing it in JavaScript.

Analyzing the traverseData code, it appears to

  • Attempt to find nodes in an object structure (the outermost data argument value) with an own property key matching a key string value passed as the obj argument.
  • If existing matching named properties are found, their values are updated to newValue.
  • If no matching property names are found, traverseData returns without making changes.
  • Property names would need to be unique among root and all sub-objects within the data structure to prevent multiple object properties being updated in a single call. Updating all copies of the same property name could, however, be a design objective and deliberate.

In addition

data[k] = traverseData(data[k], obj, newValue);

is setting data[k] to its existing value upon return from a recursive call. Should it be necessary the return value of traverseData could be used to return other values, such as a boolean indication of whether a property has been updated or not.


Different ways of adding a new property to the ocrData object include

  • adding it as a field to all existing ocrData data objects in a data base used to save and retrieve records to recreate the object model posted in the question,

  • if it doesn't already exist, add it with a default value to the parsed JSON data in JavaScript before calling traverseData, e.g.:

        const dataRoot = JSON.parse(/*JSON text*/);
        const defaultPaymentTerms = ""; // some chosen default
        if( !dataRoot.invoice.ocrData.hasOwnProperty("paymentTerms")) {
            dataRoot.invoice.ocrData.paymentTerms = defaultPaymentTerms;
        }
        ...
        traverseData( dataRoot, "paymentTerms", "30 days"); // update record.
    

This answer does not look into how to insert a property at a specific place in the (ES6) order of object properties. However, JSON implementations need not respect object property ordering, making the question of it largely academic. See "Is the order of elements in a JSON list preserved?" for discussion.

traktor
  • 17,588
  • 4
  • 32
  • 53