Oboe.js - how to work with chainable method and retrieving ancestor value

409 views Asked by At

I am using oboe.js and and i want to retrieve data from the node "sections" and also map the ancestor profile_namespace and owner_name to the data retrieve from sections node (see json file extract below).

JSON FILE EXTRACT (myjson.json):

{
  "data": [{
    "profile_namespace": "DS",
    "tutorial": {
      "owner_name": "Dominic",
      "picture_url": "/picture.jpg",
      "title": "The code",
      "url": "/Dominic/thecode/",
      "sections": [{
        "episode_url": "/tutorial/intro/symphony-of-war/",
        "artist": "MasterOrchestra",
        "title": "Symphony of War"
      }, {
        "episode_url": "/tutorial/mainshow/musicproductiontip1/",
        "artist": "DStone",
        "title": "Music production tip 1"
      }, {
        "episode_url": "/tutorial/outrothe/nextshow/",
        "artist": "MasterOrchestra",
        "title": "Next show"
      }]
    }
  }]
}

Right now i am only able to retrieve data from the node "sections" but i saw in the documentation that .node return chainable method and that it is possible to use the notion of "ancestors" to retrieve data from the parent.

Does anyone can explain me how to use this method (see my code below)?

CODE

var oboe = require('oboe');
var fs = require('fs');
var SetList = require('fs');
var setList = [];
var showInfo = require('fs');

oboe(fs.createReadStream('/myjson.json'))
    .node({
        'sections': function(node) {
            setList.push(node);
            showInfo = fs.createWriteStream('/showInfo.json');
            showInfo.write(JSON.stringify(setList));
        }
    });

Thanks for your help!

Dominic

1

There are 1 answers

4
JuanCaicedo On BEST ANSWER

Let me know if I misunderstood parts of your question and I update my answer.

Using ancestors in Oboe

The callback function you pass to a node listener will fire with three arguments. The first is the node in the tree which has been matched, the second will be an array representing the path to that node, and the third will an array of objects representing the ancestors of that node. This is documented near the end of the node-event section of the API.

.node({
    'sections': function(sections, path, ancestors) {

      var grandparent = ancestors[ancestors.length - 2];
      console.log(grandparent.owner_name); // Dominic

      var greatGrandparent = ancestors[ancestors.length - 3];
      console.log(greatGrandparent.profile_namespace); // DS

    }
});

Other things

Here are some unrelated things I think are worth mentioning

  • You can probably remove this line, since the variable SetList is not being used.

    var SetList = require('fs');

  • You don't need to initialize setList to an instance of the fs module. Since you're going to redefine it later, you can just declare that variable without instantiating it. Even better, you could define it within the callback since it's the only place it's used.

  • Node (at least v0.10.41) throws an error if you call fs.createReadStream or fs.createWriteStream on a string starting with '/'. I would suggest calling them with './myjson.json' and 'showInfo.json'

  • I would suggest using the shorthand way of registering a node listener in Oboe. This one is just a stylistic preference. The other syntax can be useful if you're registering multiple listeners, but I think chaining is just as good in that situation.

My suggested implementation of the code you posted

var oboe = require('oboe');
var fs = require('fs');

oboe(fs.createReadStream('./myjson.json'))
  .node('sections', function(sections, path, ancestors) {

      var mutatedSections = sections;
      // change mutatedSections however you want

      var showInfo = fs.createWriteStream('./showInfo.json');
      showInfo.write(JSON.stringify(mutatedSections));

    }
  });