1

I have two JSON files. I want to compare the JSON objects in both files; json1 and json2. If there is an object in the array in the first json file (json1) file that is not present in second json file (json2), I would like to pass it through the below Nightmare js code then push it the object to the second json file using .push().


JS CODE:

var Nightmare = require('nightmare');
var nightmare = Nightmare({
  show: true
});
var json1 = require('./json1.json')
var json2 = require('./json2.json')

for (var i = 0; i < json1.length; i++) {
  for (var c = 0; c < json2.length; c++) {
    if (json1[i] !== (json2[c])) {
      console.log(json1[i])
      return nightmare
        .goto(json1[0].searchOn)
        .insert('.gLFyf', json1[0].searchText)
        .wait(3000)
        .end()
        .evaluate((json2, json1) => {
          return json2[c].push(json1[i])
        }, json2, json1)
        .then()
    } else {
      console.log('End!')
    }
  }
}

JSON1 Data

[
    {
        "searchOn": "https://www.google.com",
        "searchText": "I love google"
    },
    {
        "searchOn": "https://www.google.com",
        "searchText": "I'm hungry, where can I eat?'"
    }
]

JSON2 Data

[
    {
        "searchOn": "https://www.google.com",
        "searchText": "What's the date?"
    },
    {
        "searchOn": "https://www.google.com",
        "searchText": "What is the internet"
    },
    {
        "searchOn": "https://www.google.com",
        "searchText": "What's the weather like today?"
    }
]

However, the Js code gives me this error: UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'push' of undefined.

The code also does not execute the nightmare js code on all objects on the loop (only performs the task for the first item alone.

Please advice on how I can fix these errors.

Kind regards.

Charlie
  • 1,169
  • 2
  • 16
  • 31
Leon Peter
  • 139
  • 1
  • 1
  • 7

2 Answers2

0

You can't iterate through an object by indexes. This would work with arrays, which are a type of object with keys mapped to indexes starting at 0. If you want to iterate through any object use Object.keys or for-in operator. You can find out how to do both here.

The same is true about push, which is an array method

0

The interaction between multiple code errors can be difficult to predict and/or explain. Here's a few to review:

  1. if (json1[i] !== (json2[c]))

The entries in json1 and json2 are objects created by JSON.parse. They are always different objects. Comparing equality of their primitive property values will be needed to see if the objects contain the same data.

  1. return nightmare ...

This would synchronously return the pending promise returned by then() at the end of the promise chain from the function in which this code is executing, so only the first loop iteration is performed. The return keyword needs to be removed for the loop to complete.

  1. json2[c].push(json1[i] in one of the call backs

has two problems:

a) it is executed asynchronously. If the return is removed and the loop completes, c and i are equal to the length of json2 and json respectively and return undefined if used as array indices. This is an asynchronous programming issue - refer to JavaScript closure inside loops – simple practical example for solutions.

b) json2[c] is a plain object, not an array, so it doesn't have a push method. You probably meant to push a value on the end of json2, not onto an entry in it.

  1. There is no catch clause on the nightmare promise chain. Uncaught promise rejection errors may become fatal in the future.

Note I have no exact reason why json2[c] is undefined in the code snippet - are you quoting from actual code rather than the cut down example posted? I would also suggest looking into asynchronous functions and the await operator as a means of looping asynchronous operations.

traktor
  • 17,588
  • 4
  • 32
  • 53