0

**UPDATE**

/* This is my file in Node: */

var Crawler = require("crawler");
const fs = require('fs');

function iterObj(obj) {
let arr = []
let objValues = Object.values(obj);
// use var to avoid additonal heap overhead of new variable for each iteration
for (var i = 0, len = objValues.length; i < len; i++) {
    if (objValues[i] !== null) {
        if (objValues[i].children || objValues[i].next || objValues[i].prev || objValues[i].parent) {
            delete objValues[i].children;
            delete objValues[i].next;
            delete objValues[i].prev;
            delete objValues[i].parent;
        }
        if (objValues[i].src) { arr.push({ src: objValues[i].src }) }

        console.log("contents of arr on line 29 ", arr);
        if (typeof objValues[i] === "object" && !Array.isArray(objValues[i])) {
            arr.push(...iterObj(objValues[i]));
        }
    }
}
return arr;
}



var c = new Crawler({
maxConnections: 10,
// This will be called for each crawled page
callback: function(error, res, done) {
    if (error) {
        console.log(error);
    } else {
        var $ = res.$;
        // $ is Cheerio by default
        //a lean implementation of core jQuery designed specifically for the server;
        var img = $(`img`);

        console.log('img', img);
        console.log('iterObj(img)', iterObj(img))


        // fs.writeFile('fragrance.js', img, (err) => {
        //     if (err) throw err;
        //     console.log(`img`, img);
        //     console.log(`iterObj(img)`, iterObj(img));


        //     console.log('Data written to file.')
        // })

    }
    done();
}
});


c.queue('https://www.elizabetharden.com/fragrance/')


And this is the data, a javascript object.

img initialize {
  '0':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         '/on/demandware.static/Sites-ElizabethArden-Site/-/default/dwbde506b9/images/ELIZABETH_ARDEN_LOGO_640x90.png',
        alt: 'Elizabeth Arden' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'picture',
        attribs: {},
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '1':
   { type: 'tag',
     name: 'img',
     attribs:
      { alt: 'Fragrance Collection',
        src:
         'https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dwd973092c/images/category-landing/D_White_Tea_Fragrance_Page_Banner-bg.jpg',
        srcset:
         'https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dwd973092c/images/category-landing/D_White_Tea_Fragrance_Page_Banner-bg.jpg, https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dw62e6fa40/images/category-landing/D_White_Tea_Fragrance_Page_Banner@2x-bg.jpg 2x' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'picture',
        attribs: {},
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '2':
   { type: 'tag',
     name: 'img',
     attribs:
      { alt: 'My Fifth Avenue Fragrance',
        src:
         'https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dw255d9a03/images/category-landing/myfifthavenue_1100x1100.jpg',
        srcset:
         'https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dw255d9a03/images/category-landing/myfifthavenue_1100x1100.jpg' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'picture',
        attribs: {},
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '3':
   { type: 'tag',
     name: 'img',
     attribs:
      { alt: 'Elizabeth Arden Green Tea Perfume',
        src:
         'https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dw8c63d4b5/images/category-landing/green-tea_1100x1100.jpg',
        srcset:
         'https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dw8c63d4b5/images/category-landing/green-tea_1100x1100.jpg' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'picture',
        attribs: {},
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '4':
   { type: 'tag',
     name: 'img',
     attribs:
      { alt: 'Elizabeth Arden White Tea Perfume',
        src:
         'https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dw489093d9/images/category-landing/white-tea_1100x1100.jpg',
        srcset:
         'https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dw489093d9/images/category-landing/white-tea_1100x1100.jpg' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'picture',
        attribs: {},
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '5':
   { type: 'tag',
     name: 'img',
     attribs:
      { alt: 'Skincare Diagnostic',
        src:
         'https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dw51ed6763/images/category-landing/red-door_1100x1100.jpg',
        srcset:
         'https://www.elizabetharden.com/on/demandware.static/-/Sites-ElizabethArden-Library/default/dw51ed6763/images/category-landing/red-door_1100x1100.jpg' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'picture',
        attribs: {},
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '6':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dwc531e5e7/images/2104_A0115075.jpg?sw=550&sh=550&sm=fit',
        alt: 'My Fifth Avenue Eau de Parfum, , large',
        class: 'desktop-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: null,
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '7':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dwc531e5e7/images/2104_A0115075.jpg?sw=550&sh=550&sm=fit',
        alt: 'My Fifth Avenue Eau de Parfum, , large',
        class: 'ipad-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '8':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dwc531e5e7/images/2104_A0115075.jpg?sw=135&sh=136&sm=fit',
        alt: 'My Fifth Avenue Eau de Parfum, , large',
        class: 'iphone-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '9':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dwbb9e72e0/images/1003A0106574.jpg?sw=550&sh=550&sm=fit',
        alt: 'Elizabeth Arden White Tea Eau de Toilette Spray, , large',
        class: 'desktop-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: null,
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '10':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dwbb9e72e0/images/1003A0106574.jpg?sw=550&sh=550&sm=fit',
        alt: 'Elizabeth Arden White Tea Eau de Toilette Spray, , large',
        class: 'ipad-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '11':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dwbb9e72e0/images/1003A0106574.jpg?sw=135&sh=136&sm=fit',
        alt: 'Elizabeth Arden White Tea Eau de Toilette Spray, , large',
        class: 'iphone-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '12':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dw55f80ff7/images/100326800.jpg?sw=550&sh=550&sm=fit',
        alt: 'Green Tea Scent Spray, , large',
        class: 'desktop-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: null,
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '13':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dw55f80ff7/images/100326800.jpg?sw=550&sh=550&sm=fit',
        alt: 'Green Tea Scent Spray, , large',
        class: 'ipad-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '14':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dw55f80ff7/images/100326800.jpg?sw=135&sh=136&sm=fit',
        alt: 'Green Tea Scent Spray, , large',
        class: 'iphone-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '15':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dw0dcf8cae/images/10034372400.jpg?sw=550&sh=550&sm=fit',
        alt: 'Green Tea Honey Drops Body Cream, , large',
        class: 'desktop-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: null,
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '16':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dw0dcf8cae/images/10034372400.jpg?sw=550&sh=550&sm=fit',
        alt: 'Green Tea Honey Drops Body Cream, , large',
        class: 'ipad-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '17':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dw0dcf8cae/images/10034372400.jpg?sw=135&sh=136&sm=fit',
        alt: 'Green Tea Honey Drops Body Cream, , large',
        class: 'iphone-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '18':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dwc687b1bb/images/2104-A0119537-Red-Door-Fragrance-3.3oz-4-Piece-Set.jpg?sw=550&sh=550&sm=fit',
        alt: 'Red Door 3.3oz Eau De Toilette 4-Piece Set, , large',
        class: 'desktop-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: null,
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '19':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dwc687b1bb/images/2104-A0119537-Red-Door-Fragrance-3.3oz-4-Piece-Set.jpg?sw=550&sh=550&sm=fit',
        alt: 'Red Door 3.3oz Eau De Toilette 4-Piece Set, , large',
        class: 'ipad-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '20':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dwc687b1bb/images/2104-A0119537-Red-Door-Fragrance-3.3oz-4-Piece-Set.jpg?sw=135&sh=136&sm=fit',
        alt: 'Red Door 3.3oz Eau De Toilette 4-Piece Set, , large',
        class: 'iphone-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '21':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dw86b39b0f/images/2104_Pomegranate.jpg?sw=550&sh=550&sm=fit',
        alt: 'Green Tea Pomegranate  Eau De Toilette Spray, , large',
        class: 'desktop-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: null,
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '22':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dw86b39b0f/images/2104_Pomegranate.jpg?sw=550&sh=550&sm=fit',
        alt: 'Green Tea Pomegranate  Eau De Toilette Spray, , large',
        class: 'ipad-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: [Object],
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  '23':
   { type: 'tag',
     name: 'img',
     attribs:
      { src:
         'https://www.elizabetharden.com/dw/image/v2/AAHP_PRD/on/demandware.static/-/Sites-elizabetharden-master-catalog/default/dw86b39b0f/images/2104_Pomegranate.jpg?sw=135&sh=136&sm=fit',
        alt: 'Green Tea Pomegranate  Eau De Toilette Spray, , large',
        class: 'iphone-only' },
     children: [],
     next:
      { data: '\n',
        type: 'text',
        next: null,
        prev: [Circular],
        parent: [Object] },
     prev:
      { data: '\n',
        type: 'text',
        next: [Circular],
        prev: [Object],
        parent: [Object] },
     parent:
      { type: 'tag',
        name: 'a',
        attribs: [Object],
        children: [Array],
        next: [Object],
        prev: [Object],
        parent: [Object] } },
  options:
   { normalizeWhitespace: false,
     xmlMode: false,
     decodeEntities: true,
     withDomLvl1: true },
  _root:
   initialize {
     '0':
      { type: 'root',
        name: 'root',
        attribs: {},
        children: [Array],
        next: null,
        prev: null,
        parent: null },
     options:
      { normalizeWhitespace: false,
        xmlMode: false,
        decodeEntities: true,
        withDomLvl1: true },
     length: 1,
     _root: [Circular] },
  length: 24,
  prevObject:
   initialize {
     '0':
      { type: 'root',
        name: 'root',
        attribs: {},
        children: [Array],
        next: null,
        prev: null,
        parent: null },
     options:
      { normalizeWhitespace: false,
        xmlMode: false,
        decodeEntities: true,
        withDomLvl1: true },
     length: 1,
     _root: [Circular] } }
var initialize = {
      '0': {   
         type: 'tag',
         name: 'img',
         attribs: { 
            src: 'path/to/file.png',
            alt: 'SEO is good' 
         },
       },
      '1': { 
         type: 'tag',
         name: 'img',
         attribs: { 
             src: 'path/to/another/image.jpg',
            alt: 'SEO is GREAT' 

         }
       }

I have an object and want to traverse recursively until I get to my property and value I wish.

Isn't this how you would do it ?

function iterObj(obj) {
  var arr = []
  arr.push(obj)
  return arr.map(obj => {
    var newObj = {}
    if (obj !== null && typeof obj === "object") {
      iterObj(obj);
    }
    newObj[obj.src] = obj.src;
    return newObj;
  })
}

So shouldn't iterObj(initialize) yield:

[{src: 'path/to/file.png'}, {src: 'path/to/another/image.jpg'}]

UPDATE:

Might help to include the context where I am using this:

Below is a scraper module I am using in node.

var Crawler = require("crawler");
const fs = require('fs');
   
function IsJsonString(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}

function iterObj(obj) {
    var arr = []
    var isNotNull = (value) => typeof value !== "object" && value !== null

    for (var value of Object.values(obj)) {
        console.log("value line 18", value);

        if (value !== null) {
            if (value.src) { arr.push({ src: value.src }) }
            if (typeof value === "object" && !Array.isArray(value)) {
                console.log("value line 23", value);

                arr.push(...iterObj(value));
            }
        }
    }
    return arr;
}



var c = new Crawler({
    maxConnections: 10,
    // This will be called for each crawled page
    callback: function(error, res, done) {
        if (error) {
            console.log(error);
        } else {
            var $ = res.$;
            // $ is Cheerio by default
            //a lean implementation of core jQuery designed specifically for the server;
            var img = $(`img`);
            fs.writeFile('fragrance.js', img, (err) => {
                if (err) throw err;
                console.log(`img`, img);
                console.log(`iterObj(obj) ${iterObj(img)}`)
                    // console.log(`IsJsonString(img)`, IsJsonString(img[0]));


                console.log('Data written to file.')
            })

        }
        done();
    }
});

c.queue('https://www.somesite.com/someendpoint/')
Antonio Pavicevac-Ortiz
  • 7,239
  • 17
  • 68
  • 141

1 Answers1

1

In order to check each property of the object, you will need to get a list of the object's properties and/or their respective values, either using Object.keys(), Object.values() or Object.entries(). From there, you will need to check if each value meets the following criteria:

1) If it has a src property, push that property and continue on

2) If it is an object, and not null, recurse over the object to check if it, or its children have a src property

Then you concatenate the results of the recursive calls to your original array and return the final results. This is one of the key pieces you were missing. You were making the recursive calls, but not doing anything with them.

The reason you can't use .map like you were, is because you're not returning a src from an object 1-to-1. An object could contain any number of child src properties, or it could contain 0. You'll need to manually build your results list instead.

Here's a working example of what you're trying to do:

var initialize = {
  '0': {   
      type: 'tag',
      name: 'img',
      attribs: { 
        src: 'path/to/file.png',
        alt: 'SEO is good',
        self: null,
        parent: null,
        top: null
      },
      next: {
        prev: null
      },
      prev: {
        next: null
      }
    },
  '1': { 
      type: 'tag',
      name: 'img',
      attribs: { 
          src: 'path/to/another/image.jpg',
        alt: 'SEO is GREAT' 

      }
    }
}

// add circular references for testing
initialize[0].attribs.self = initialize[0].attribs;
initialize[0].attribs.parent = initialize[0];
initialize[0].attribs.top = initialize;
initialize[0].next.prev = initialize[0].prev;
initialize[0].prev.next = initialize[0].next;

function iterObj(nestedObj) {
  // keep a list of object references to prevent circular references at any level
  let objReferences = [];
  function rHelper(obj) {
    let arr = []
    let objValues = Object.values(obj);
    // use var to avoid additonal heap overhead of new variable for each iteration
    for (var i = 0; i < objValues.length; i++) {
      let val = objValues[i];
      // check if non null and not a reference we've already seen before (AKA circular reference)
      if (val !== null && objReferences.indexOf(val) === -1) {
        if (val.src) { arr.push({ src: val.src }) }
        if (typeof val === "object" && !Array.isArray(val)) {
          // since we're checking this object, add reference to list to make sure it doesn't get
          // referenced by any of its children or siblings
          objReferences.push(val);
          arr.push(...rHelper(val));
        }
      }
    }
    return arr;
  }

  return rHelper(nestedObj);
}

console.log(iterObj(initialize));
mhodges
  • 10,938
  • 2
  • 28
  • 46
  • Thanks this works with the abstraction that I provided here on Stackoverflow, but i'm getting an error in my `console` in node which states. `/Users/antoniopavicevac-ortiz/Sites/compress-images/EA-site-image-compression-todo/crawler/index.js:22 if (value.src) { arr.push({ src: value.src }) } ^ TypeError: Cannot read property 'src' of null` – Antonio Pavicevac-Ortiz Jan 24 '20 at 19:36
  • 1
    @AntonioPavicevac-Ortiz Ah, okay that just means that it tried to do `if (value.src)` when `value === null`. Simply move your null check above that line and everything should work as expected. I updated my code above to reflect this change. – mhodges Jan 24 '20 at 20:09
  • Thank you my friend! Greatly appreciate it! One more thing, I'm getting a `RangeError: Maximum call stack size exceeded` I tried adding `else` cases which have `return` statements but to no avail. I updated my question to provide some context. I am using a NPM module to scrap a website to get all the image tags. – Antonio Pavicevac-Ortiz Jan 24 '20 at 21:34
  • @AntonioPavicevac-Ortiz That has to do with too many recursions, meaning either A: you are stuck in infinite recursion somehow, or B: the objects you are searching are really large or are nested very deep, or both. – mhodges Jan 24 '20 at 22:48
  • I actually pasted the object in question above. It does have some nested information, but its really just a collection of `24` first level objects. Could that really bork the function like that? – Antonio Pavicevac-Ortiz Jan 24 '20 at 23:32
  • @AntonioPavicevac-Ortiz I wouldn't think so, but I suppose it's possible? Depends how many keys the objects have. Here's some info on [calculating max stack size](https://glebbahmutov.com/blog/javascript-stack-size/) that may be useful – mhodges Jan 24 '20 at 23:42
  • 1
    @AntonioPavicevac-Ortiz Another thing you can try is using `for` instead of `for...of`. It will be much more performant and does not make any additional underlying function calls to `next` or `yield`. Maybe that's where the function stack is getting exceeded? I updated my code with basic `for` loop for you to try out – mhodges Jan 24 '20 at 23:46
  • Thanks but that didn't work. I even tried to optimize the loop with `for (var i = 0, len = objValues.length; i < len; i++) }` – Antonio Pavicevac-Ortiz Jan 25 '20 at 00:29
  • @AntonioPavicevac-Ortiz Can you post the full data set? Something is either causing an infinite loop or it's nested very deeply. I tried your example data spread across 24 properties and it handled it just fine – mhodges Jan 25 '20 at 06:57
  • I posted the data (see above), and its just a plain ole javaScript object. Thanks mate! – Antonio Pavicevac-Ortiz Jan 27 '20 at 15:55
  • @AntonioPavicevac-Ortiz Ahhh, it's because you have circular object references in your data. Notice when you posted it some of them say `[Circular]`, that means the object references itself, which, when passed through this function will recurse infinitely. I think you should be able to check to make sure that `obj[i] !== obj` and that will prevent that, but I will double check. – mhodges Jan 27 '20 at 16:56
  • @AntonioPavicevac-Ortiz I spoke too soon. The nature of how the circular references are in your data does not lend itself to an easy check, because the references can be to a parent's sibling, or to a parent's parent, not simply the parent itself. I updated my answer with how to address this, and it should work with the data you posted above. Let me know how it works for you – mhodges Jan 27 '20 at 17:24
  • 1
    @Thanks for all your help and patience my friend that worked! – Antonio Pavicevac-Ortiz Jan 27 '20 at 17:44