Add data to API results - javascript

I'm using an API which returns an array of results, let's call them "employees" and let's say it returns "employee.id" and "employee.name".
I know the "age" of each employee and I have it in a list (JSON file).
What I'm trying to achieve is: whenever a user makes a search, the app will pull results from "employees", match all the id's from "employees" to id's in my JSON file, and returns an array with "employee.id", "employee.name" and "employee.age".
Or at least that's the theory.
What is the best practice? Should the app search the API and then my JSON or both at the same time? How do I "match" the two?
I don't think the language really matters here, but I'm writing it in Node.js

Because you've provided no specifics about the API or JSON file, an answer can't be made very specific either so here's a general concept.
Use an async file access method in node.js, read the JSON file into memory and when it loads, parse it into a Javascript array.
As soon as you start the async file read, then start your API call.
When both async operations have finished (I personally would use Bluebird in nodejs to promisify both operations so they each returned a promise and would then use Promise.all() to know when both async operations were done.
Then, get the employee.id from the API call and do a search for that id in the array of employees that came from the JSON file. If you only have to do this once, you can do a brute force search through the array (just looping through the array and comparing each object in the array to see if the id matches).
Once you find the matching id in the array, you can then get the age and name from that same object and you should now have all the info you want.
If this is a common operation, then you probably want to load the JSON file just once, save it persistently in your nodejs application and you may also want to create an index by id so you can just do a direct lookup on the id rather than having to do a brute force search each time.
A brute force search of an array of objects for a particular .id property could look like this:
function findEmployeeById(id) {
for (var i = 0; i < employeeData.length; i++) {
if (employeeData[i].id === id) {
return employeeData[i];
}
}
return null;
}

Related

Firebase database. How to append values to array?

I have the following test data
1: {
match: "Game 1",
scorer: ["foo","bar"] //this could also be an object
}
My question is how do I correctly append new value to an array without overwriting it? My idea was to retrieve existing data then spread it like so [...currentData, "bob"]. Is there a better alternative?
const addScorer = (matchId) => {
return update(ref(db, path), {
scorer: ["bob"]
})
}
There is no atomic operation to add an item to an array directly in the database. This means you'll need to:
Read the array into your application code
Append the item to the array
Write the entire array back to the database
This is one of the many reasons why Firebase recommends against using arrays for lists of data, but instead has a push() operation that circumvents most problems. For more on this, see the link to the document that Nilesh included in their comment, or read this article on Best Practices: Arrays in Firebase.

Riak MapReduce in single node using javascript and python

I want to perform MapReduce job on data in Riak DB using javascript. But stuck in very begining, i couldnot understand how it is returning value.
client = riak.RiakClient()
query = client.add('user')
query.map("""
function(v){
var i=0;
i++;
return [i];
}
""")
for result in query.run():
print "%s" % (result);
For simplicity i have checked the above example.
Here query is bucket and user contain five sets of data in RiakDB.
i think map() returns single value but it returns array with 5 value, i think equivalent to five set of data in RiakDB.
1
1
1
1
1
And here, why I can return only array? it treats each dataset independently, and returns for each. so i think i have five 1's. Due to this reason when i process fetched data inside map(), returns gives unexpected result for me.
so please give me some suggestion. i think it is basic thing but i couldnot get it. i highly appreciate your help.
When you run a MapReduce job, the map phase code is sent out to the vnodes where the data is stored and executed for each value in the data. The resulting arrays are collected and passed to a single reduce phase, which also returns an array. If there are sufficiently many results, the reduce phase may be run multiple times, with the previous reduce result and a batch of map results as input.
The fact that you are getting 5 results implies that 5 keys were seen in your bucket. There is no global state shared between instances of the map phase function, so each will have an independent i, which is why each result is 1.
You might try returning [v.key] so that you have something unique for each one, or if the values are expected to be small, you could return [JSON.stringify(v)] so you can see the entire structure that is passed to the map.
You should note that according to the docs site javascript Map Reduce has been officially deprecated, so you may want to use Erlang functions for new development.

Node js couchbase query calls matching with couchbase view

I'm having issues passing parameters to a view through the node js couchbase module. The main issue is I don't know what question to ask google in order to get the answer I'm looking for. I would like to get from the view a specific object based on a key that I'm receiving from a UI.
For example, I have a list of stores with store numbers 111, 222, and 333. If the user gives me the store number 222, I'd like to only return that one, instead of return it all then filter inside my node js code.
The node js code looks like this:
var query = ViewQuery.from('dev_store', 'store').key(storeNum);
myBucket.query(query, function (err, results) {...};
I got that from the ViewQuery api mixed with this question. However I cannot figure out how to then access that key parameter once I'm in the view in order to filter down my results to just that one store.
I've tested my view and it works fine, so long as I just get a list of all the stores. I've read about reductions but I haven't seen where those actually get written/called.
I've tried accessing it by doing doc.key or adding a key to the view function, but I think my limited understanding of View construction is hurting me here.
Question: Given a key, how do I return from a view only the row that pertains to that key?
EDIT: Here is my view:
function (doc, key, meta) {
doc.midLevel.forEach( function ( reg ) {
reg.midLowerLevel.forEach( function ( dis ) {
dis.lowestLevel.forEach( function ( store ) {
emit( store.store_nbr, null);
})
})
})
}
In this view it emits every store at the lowest level. As seen in the node js code, I've passed a key to it. I would like to use that key in order to create a condition on what gets emitted.
For example, if there are stores numbered 1-100, and the node js passes the number 45, is it possible for me to access the '45' in the view in order to create that condition statement?
Question: Given a key, how do I return from a view only the row that pertains to that key?
On the face of it, this question is not relevant to a view. Views are absolutely not meant to return objects based on the object key. Rather, a view is meant to index certain properties of stored objects such that the objects can be pulled together into a list of some sort.
To return a document based on the key, you would perform a simple get operation. A view query in this scenario actually degrades performance, since the view must be accessed from disk. An object get from a view as opposed to from RAM is an order of magnitude or more slower than a simple read.
Answer: use a get, not a view.

How to convert json/object to array for looping

I have a javascript application, that calls an api, and the api returns json. With the json, I select a specific object, and loop through that.
My code flow is something like this:
Service call -> GetResults
Loop through Results and build Page
The problem though, is sometimes that api returns only one result, so that means it returns an object instead of an array, so I cant loop through results. What would be the best way to go around this?
Should i convert my object, or single result to an arrary? Put/Push it inside an array? or should I do a typeof and check if the element is an array, then do the looping?
Thanks for the help.
//this is what is return when there are more than one results
var results = {
pages: [
{"pageNumber":204},
{"pageNumber":1024},
{"pageNumber":3012}
]
}
//this is what is returned when there is only one result
var results = {
pages: {"pageNumber": 105}
}
My code loops through results, just using a for loop, but it will create errors, since sometimes results is not an array. So again, do I check if its an array? Push results into a new array? What would be better. Thanks
If you have no control over the server side, you could do a simple check to make sure it's an array:
if (!(results.pages instanceof Array)) {
results.pages = [results.pages];
}
// Do your loop here.
Otherwise, this should ideally happen on the server; it should be part of the contract that the results can always be accessed in a similar fashion.
Arrange whatever you do to your objects inside the loop into a separate procedure and if you discover that the object is not an array, apply the procedure to it directly, otherwise, apply it multiple times to each element of that object:
function processPage(page) { /* do something to your page */ }
if (pages instanceof Array) pages.forEach(processPage);
else processPage(pages);
Obvious benefits of this approach as compared to the one, where you create a redundant array is that, well, you don't create a redundant array and you don't modify the data that you received. While at this stage it may not be important that the data is intact, in general it might cause you more troubles, when running integration and regression tests.

How should i save the response data in a object(json) to have better manipulation and performance?

what i am doing is:
1. Get values from ajax response(which is in json format) for listing rows of data which
response = {"categories":[{"name":"General","id":"6305","pop":"show when clicked"},{"name":"Navigation","id":"6043","pop":"show when clicked"},{"name":"New","id":"6051","pop":"show when clicked"},{"name":"Time","id":"6117","pop":"show when clicked"},{"name":"Reesh","id":"6207","pop":"show when clicked"}]}
2 . I will parse the json and store in a object like this
ex:
object= {6305:{"name":"General","id":"6305","pop":"show when clicked"},
6043:{"name":"Navigation","id":"6043","pop":"show when clicked"},
6051:{"name":"New","id":"6051","pop":"show when clicked"},
6117:{"name":"Time","id":"6117","pop":"show when clicked"},
6207:{"name":"Reesh","id":"6207","pop":"show when clicked"}};
why i am doing this is because i can get the data using the id
ex: object[6305] will give me the data.
3 .So that i can retrieve the data and also make changes to values in the object using the id when changes occur in db.
ex: object[6350].pop="changed";
Please tell me:
-->whether is this the correct method or i can do it in a much simpler or efficient way?
-->whether i can store the json response as it is and parse data as it is? if so please explain with example.
Yes, of course you would not need to build the object:
function getObject(id) {
for (var i=0; i<response.categories.length; i++)
if (response.categories[i].id == id)
return response.categories[i];
return null;
}
However, if you often need to access objects by their ids this function would be slow. Creating the lookup table as you did will not create much memory overhead, but make retrieving data much faster.
BTW: Your title question "save data as object or json" is confusing. Serializing manipulated objects back to JSON makes no sense, as you always will use the parsed objects. Of course, if you just needed to manipulate a JSON string, and knew exactly what to do, (simple) string manipulation could be faster than parsing, manipulating and stringifying.

Categories

Resources