4

I am new to node.js and kind of stuck here. I have a json file keyValue.json which resembles this

[ {
    "key": "key1",
    "value": "value1"
  },   
  {
    "key": "key2",
    "value": "value2"
  } 
]

For a particular key I need to get the value.

function filterValue() {
  const category = {};
  category.filter = "key1" //this is not static value. This changes dynamically
  category.value = //Need to read the keyValue.json file and pick the value for key1 - which is value1
  return category;
}

How can this be achieved in node.js. Thanks for helping out.

5
  • Possible duplicate of Find object by id in an array of JavaScript objects Commented Jan 5, 2019 at 1:33
  • It is different from the above in 2 aspects. 1. I am not looking up a static value 2. I want to be able to read from a file Commented Jan 5, 2019 at 1:58
  • Whether it can change or not doesn't matter, you can still use the method used in the linked question. Commented Jan 5, 2019 at 1:59
  • The example uses an array. Mine is a file. do I need to read the file into an array to do this? Commented Jan 5, 2019 at 2:02
  • See here eg this Commented Jan 5, 2019 at 2:05

2 Answers 2

10

I am assuming that you have your json parsed into a variable. So my example will use this:

const data = [ 
  {
    key: "key1",
    value: "value1"
  },   
  {
    key: "key2",
    value: "value2"
  } 
];

If not, then in node we can just require it as long as it is a static file. But this will be loaded once for the execution span of the app.

const data = require('./file.json');

If it needs to be dynamically read because it is changing for some reason then you need to use fs (always do it async in node).

const fs = require('fs');

fs.readFile('./file.json', 'utf8', function(err, contents) {
    if (err) {
      // we have a problem because the Error object was returned
    } else {
      const data = JSON.parse(contents);
      ... use the data object here ...
    }
});

If you prefer Promises to callbacks:

const fs = require('fs');

// ES7 Version
const getJsonFile = (filePath, encoding = 'utf8') => (
   new Promise((resolve, reject) => {
      fs.readFile(filePath, encoding, (err, contents) => {
          if(err) {
             return reject(err);
          }
          resolve(contents);
      });
   })
     .then(JSON.parse)
);

// ES6 Version
const getJsonFile = function getJsonFile(filePath, encoding = 'utf8') {
   return new Promise(function getJsonFileImpl(resolve, reject) {
      fs.readFile(filePath, encoding, function readFileCallback(err, contents) {
          if(err) {
             return reject(err);
          }
          resolve(contents);
      });
   })
     .then(JSON.parse);
};

Now with either of these you can simply use the Promise

getJsonFile('./file.json').then(function (data) { ... do work });

or if using async

const data = await getJsonFile('./file.json');

So now we would want a composable filter to use with Array's find method. In the latest versions of Node (Carbon and above):

const keyFilter = (key) => (item) => (item.key === key);

If you are node 6 or below lets do this the old way

const keyFilter = function keyFilter(key) {
   return function keyFilterMethod(item) {
      return item.key === key;
   }
};

Now we can use this filter on the array changing out the key we are looking for at any time (because it is composable).

const requestedItem = data.find(keyFilter('key2');

If the key doesn't exist undefined will be returned, otherwise, we have the object.

const requestedValue = requestedItem ? requestedItem.value : null;

This filter can also be used for other searches in the Array such as finding the index

const index = data.findIndex(keyFilter('key2'));

If "key" was allowed to be duplicated in the array, you could grab them all using filter

const items = data.filter(keyFilter('key2'));

To sum it all up we would probably put our areas of concern in different files. So maybe a getJsonFile.js and a keyFilter.js so now put together we would look something like this (calling this file readKeyFromFile):

const getJsonFile = require('./getJsonFile');
const keyFilter = require('./keyFilter');

module.exports = async (filePath, keyName) => {
   const json = await getJsonFile(filePath);
   const item = json.find(keyFilter(keyName));
   return item ? item.value : undefined;
};

and our consumer

const readKeyFromFile = require('./readKeyFromFile');

readKeyFromFile('./file.json', 'key2').then((value) => {
   console.log(value);
};

There are so many combinations of how you can do this once these fundamentals are understood. So have fun with them. :)

Sign up to request clarification or add additional context in comments.

1 Comment

in the second to last code snippet const json = getJsonFile(filePath); should be const json = await getJsonFile(filePath);. Excellent answer though.
-1

If you are having json object named keyValue. first import it and named it as keyValue, then try this,

function filterValue(req, res, next) {
  keyValue
     .find({ key: "key1" })
     .exec()
     .then(result => {
        return result.value
     })  
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.