Builtin Query Capabilities in JSON using Javascript or JQuery - json

I am looking query the JSON data based on some where conditions for ex. list the person names whose cell no is 777-777-7777.
pl let me know what are query capabilities in JSON.
var json = [{
"name": "senthil",
"Phoneno": [{
"Home": "111-111-1111"
},
{
"Cell": "222-222-2222"
},
{
"Office": "333-333-3333"
}
],
"City": "Hartford"
},
{
"name": "kumar",
"Phoneno": [{
"Home": "444-555-6666"
},
{
"Cell": "777-777-7777"
},
{
"Office": "888-888-8888"
}
],
"City": "Austin"
},
];

var people = json.filter(function(el)
{
return el.Phoneno.some(function(number)
{
return number.Cell == "777-777-7777";
});
});
This uses the Array.filter and Array.some functions from ECMAScript 5. filter returns an array of the elements that pass a test. some returns true if any element in an array passes the test.
For browsers that don't support it, you can use the code at MDC.
This will almost certainly not be faster than the obvious for-loop approach.
As a note, if every person can have up to one phone number per type, a simpler representation would be:
"Phoneno": { "Home": "111-111-1111",
"Cell": "222-222-2222",
"Office": "333-333-3333"
}
Also, JSON technically refers to the text representation, not actual JavaScript objects.

Related

How to get data of a JSON file (typescript)

Hi I got a bit stuck at trying to understand how to fetch data of a JSON file.
environment.ts:
export const environment = {
production: false,
urlListBooks: "/assets/list-books.json",
urlGetBooks: "/assets/edit-book.json?:id",
urlGetTags: "/assets/edit-book.json?:tags",
urlPostBooks: "/assets/edit-book.json",
urlListTags: "/assets/list-tags.json",
urlPostTags: "/assets/edit-tag.json"
};
edit-book.json:
"book":{
"id": 1,
"title": "The Shining",
"authorId": 1,
"tags": [{"name":"new"}, {"name":"test"}]
},
"authors":[
{
"id": 1,
"prename": "Stephen",
"surname": "King"
},
{
"id": 3,
"prename": "Algernon",
"surname": "Blackwood"
},
{
"id": 4,
"prename": "Edgar Allan",
"surname": "Poe"
},
{
"id": 5,
"prename": "Howard Phillips",
"surname": "Lovecraft"
}
],
"tags":[
{
"name": "new"
},
{
"name": "Horror"
},
{
"name": "Romance"
}
]
}
service:
getBookTags(n: String) Observable<Tag[]>{
return this.http.get<Tag[]>(environment.urlGetTags.)
}
what I want getBookTags(n: String) to do is returning the tags array of the book with title n defined in the edit-book.json (e.g. "tags": [{"name":"new"}, {"name":"Horror"}] ) so that I can later use the function to check which tags a book has and select them.
Your help would be very appreciated :)
Ok I think I've solved this for you, I'm going to walk through my process with you so you understand what the goal is. You can see my solution here: https://codesandbox.io/s/thirsty-minsky-g6959f?file=/assets/edit-book.json:0-752
First thing is that your JSON you provided doesn't really make much sense, it shows multiple authors and just one "book". I think instead you want multiple books. Secondly, it's gotta be wrapped in a curly brace as shown:
{
"books": [
{
"id": 1,
"title": "The Shining",
"authorId": 1,
"tags": [{ "name": "new" }, { "name": "test" }]
},
{
"id": 2,
"title": "The Wendigo",
"authorId": 2,
"tags": [{ "name": "Horror" }]
}
],
"authors": [
{
"id": 1,
"prename": "Stephen",
"surname": "King"
},
{
"id": 3,
"prename": "Algernon",
"surname": "Blackwood"
},
{
"id": 4,
"prename": "Edgar Allan",
"surname": "Poe"
},
{
"id": 5,
"prename": "Howard Phillips",
"surname": "Lovecraft"
}
],
"tags": [
{
"name": "new"
},
{
"name": "Horror"
},
{
"name": "Romance"
}
]
}
Now, in your Typescript code we want to have typings for the json you're going to fetch. This will make your code more readable, it will give you intellisense, and help you catch some errors before you try to run your code. So we are going to go ahead and type the properties of the JSON as follows:
type Tag = {
name: string;
};
type Book = {
id: number;
title: string;
authorId: number;
tags: Tag[];
};
type Author = {
id: number;
prename: string;
surname: string;
};
type BookData = {
books: Book[];
authors: Author[];
tags: Tag[];
};
Basically what I said is we have bookdata which is made up of books, authors, and tags. Books have properties given under type Book, same thing with Author and Tag.
Now for the actual running code, we are going to use the fetch api to get the json data at the url.
async function getBookTags(n: string): Promise<Book[]> {
return fetch(url)
.then<BookData>((res) => res.json())
.then((data) => data.books)
.then((books) => books.filter((b) => doesBookHaveTag(b, n)));
}
First thing we do is fetch the data from the api, this returns a promise which when resolved (this is what .then does) we take the response and parse it for a json. Then when that promise resolves we get the books in the data. Then when that promise resolves we filter in books that have the matching tag.
doesBookHaveTag is just a little helper function I defined:
function doesBookHaveTag(book: Book, n: string): boolean {
// just return if book has at least one tag matching n
return book.tags.some((t) => t.name.toLowerCase() === n.toLowerCase());
}
If you don't understand promises you should watch some videos on it, but basically the browser sends out an http request and then when it resolves it queues a task to execute the function [see endnote] in .then when it has time. So when we want to call your async function and say log all books with the tag "horror" we do it as shown:
getBookTags("horror").then(console.log); // returns the one book.
I hope this makes sense and you can sort of see how to fetch the data, how to handle the promise it returns, and how to type your response. The only thing I'm not sure on is how Angular changes this for you (I'm a react guy), but this is really just non-library specific Javascript/Typescript.
[endnote] when I say function in .then, what I mean is that .then(data => data.books) is passing a function into the .then function. data => data.books is actually a function the same as:
function(data: BookData): Book[] {
return data.books
}

Build a JSON document from a sqlite table

I've been looking at the JSON1 extension for SQLite databases as a potential tool to use to compose a JSON document from a table-valued result.
I have a result set coming out of my SQLite database that resembles something like this:
CLASS|INSTANCE|PROPERTY|FROM|TO
ABC|12345|COLOR|RED|
ABC|12345|COLOR|GREEN|
ABC|12345|WEIGHT|1|10
ABC|56789|COLOR|BLUE|
ABC|56789|HEIGHT|4.5|6.2
DEF|2345|NAME|YOMOMMA|
I've been trying to make a JSON document based off of this data to look like:
{
"ABC": {
"12345": {
"COLOR": [
{ "from": "RED", "to": "" },
{ "from": "GREEN", "to": ""}
],
"WEIGHT": [
{ "from": "1", "to": "10" }
]
},
"56789": {
"COLOR": [
{ "from": "BLUE", "to": "" }
],
"HEIGHT": [
{ "from": "4.5", "to": "6.2" }
]
}
},
"DEF": {
"2345": {
"NAME": [
{ "from": "YOMOMMA", "to": "" }
]
}
}
}
I've been trying to get the JSON1 functions to help me out with this, but it seems they don't really support a multilayered JSON format (or at least, not that I've been able to see). If I wrap my result set in a group by query, I can get the properties to nicely turn into a JSON array, but when I try to wrap that into the next level, all the JSON gets escaped (would have been nice if there was a json_raw() function, but I'd imagine implementing it would be challenging).
Can this be done (relatively) easily using SQLite/ JSON1? Is there a different/ better way to create my document than using JSON1, or am I just going to have to write code for this?

How to fetch inner node of JSON using freemarker?

Sample JSON:
{
"results": [
{
"_id": "12345",
"CustomerAccount": {
"Status": "ACTIVE",
"Address": [
{
"FormatCode": "PRIM",
"FreeFormatAddress": "ENGLAND"
},
{
"FormatCode": "SEC",
"FreeFormatAddress": "IRELAND"
}
]
},
"LegalVehicleID": "01",
"BrokerAccount": {
"Status": "ACTIVE",
"Address": [
{
"FormatCode": "PRIM123",
"FreeFormatAddress": "SG"
},
{
"FormatCode": "SEC123",
"FreeFormatAddress": "IND"
}
]
}
}
]
}
So i want to get Address as list regardless of CustomerAccount or BrokerAccount.
result.*.Address and then access FormatCode and FreeFormatAddress using FreeMarker.
Please let me know how to do so thanks.
There's no such feature in the template language itself. Such things can be achieved with a TemplateModel that was designed to do queries against JSON, similarly as such queries are possible against XML (W3C DOM to be more precise) out-of-the-box. But I'm not aware of anybody has written such thing for JSON (and even then it's question what Java objects represent the JSON... like, is it Jackson JsonNode-s?).

couchdb ; how get documents directly in first level of json, and not grouped inside value - viewWithList

I have a design document: 'accounts',and the view: 'accounts-view'
the view's content is:
function (doc) {
emit( doc._id, doc);
}
And my code in express is:
db.view('accounts', 'accounts-view', function(err, body) {
if (err) throw error;
res.json(body.rows);
});
Result is:
[
{
"id": "8767d3474a0e80dd0ab7d0b0580065af",
"key": "8767d3474a0e80dd0ab7d0b0580065af",
"value": {
"_id": "8767d3474a0e80dd0ab7d0b0580065af",
"_rev": "1-37eb3e76e4715e9a4fc8930470cc4ca3",
"type": "accounts",
"lastname": "Kitchen",
"firstname": "Peter"
}
},
{
"id": "8767d3474a0e80dd0ab7d0b058006e3c",
"key": "8767d3474a0e80dd0ab7d0b058006e3c",
"value": {
"_id": "8767d3474a0e80dd0ab7d0b058006e3c",
"_rev": "1-bcab94bb253c83b4951a787c253896f5",
"type": "accounts",
"lastname": "Kolner",
"firstname": "John"
}
}
]
How i can get just something like this: ( just printing all is inside value for every row)
[
{
"_id": "8767d3474a0e80dd0ab7d0b0580065af",
"_rev": "1-37eb3e76e4715e9a4fc8930470cc4ca3",
"type": "accounts",
"lastname": "Kitchen",
"firstname": "Peter"
},
{
"_id": "8767d3474a0e80dd0ab7d0b058006e3c",
"_rev": "1-bcab94bb253c83b4951a787c253896f5",
"type": "accounts",
"lastname": "Kolner",
"firstname": "John"
}
]
UPDATE:
I've follow Domonique's suggestions ; and now I have a new view, that emit just the id (so i can save space on disk and retrive de doc with the parameter "include_docs=true" on the view):
function(doc) {
if (doc.type && doc.type=='accounts') {
emit( doc._id);
}
}
and a new list:
function(head, req) {
provides('json', function() {
var results = [];
while (row = getRow()) {
//results.push(row.value);
results.push(row.doc);
}
send(JSON.stringify(results));
});
}
Finally i get the records with:
http://127.0.0.1:5984/crm/_design/crmapp/_list/accounts-list/accounts-view?include_docs=true
and the result is:
[
{
"_id": "8767d3474a0e80dd0ab7d0b0580065af",
"_rev": "1-37eb3e76e4715e9a4fc8930470cc4ca3",
"type": "accounts",
"lastname": "Kitchen",
"firstname": "Peter"
},
{
"_id": "8767d3474a0e80dd0ab7d0b058006e3c",
"_rev": "1-bcab94bb253c83b4951a787c253896f5",
"type": "accounts",
"lastname": "Kolner",
"firstname": "John"
},
{
"_id": "8767d3474a0e80dd0ab7d0b058008e9a",
"_rev": "1-86078f00be82b97499a0f52488cefbbf",
"lastname": "Tower",
"firstname": "George",
"type": "accounts"
}
]
my app node express updated:
db.viewWithList('crmapp', 'accounts-view','accounts-list', {"include_docs":"true"} , function(err, body) {
if (err) throw err;
res.json(body);
});
with this list , I don't need more reduce it on express project, it's ok ?
How to udate my list or view to get by id ? it'not working just adding id on the url ; like this:
http://127.0.0.1:5984/crm/_design/crmapp/_list/accounts-list/accounts-view?include_docs=true&_id=8767d3474a0e80dd0ab7d0b058006e3c
I get all the records and not the only one by id
To answer your question here, you should simply map the array and only include the value portion:
db.view('accounts', 'accounts-view', function(err, body) {
if (err) throw error;
res.json(body.rows.map(function (row) {
return row.value;
}));
});
Since it's apparent you are new to CouchDB, I'll also give you some advice regarding views. First, the view you've created is actually just a duplicate of the system view _all_docs, so you should just use that instead rather than creating your own view. (especially since you've effectively created a duplicate on disk)
However, it is probably pretty likely that as you get further along in your application, you'll be using real views that partition documents differently depending on the query. As such, you should not emit your entire document (ie: doc) in your view function. By doing this, you are effectively duplicating that document on disk, since it will be represented in your database, as well as the view index.
The recommended starting point is to simply leave out the 2nd argument of your emit.
function (doc) {
emit(doc._id);
}
When you query the view, you can simply add include_docs=true to the URL and your view will look something like this:
[
{
"id": "8767d3474a0e80dd0ab7d0b0580065af",
"key": "8767d3474a0e80dd0ab7d0b0580065af",
"value": null,
"doc": {
"_id": "8767d3474a0e80dd0ab7d0b0580065af",
"_rev": "1-37eb3e76e4715e9a4fc8930470cc4ca3",
"type": "accounts",
"lastname": "Kitchen",
"firstname": "Peter"
}
}
// ...
]
Then, you can retrieve the doc instead of value to achieve the same result much more efficiently.

Select2 json data not working

I am trying to hook select2 when an element has class "select2picker" i am also customising if the source of the dropdown list is an array. My code below
$('.select2picker').each(function() {
var settings = {};
if ($(this).attr('data-json')) {
var jsonValue = JSON.parse($(this).attr('data-json')).val());
settings = {
placeholder: $(this).attr('data-placeholder'),
minimumInputLength: $(this).attr('data-minimumInputLength'),
allowClear: true,
data: jsonValue
}
}
$(this).select2(settings);
});
but the result is horrible it fails to hook all the select2 dropdownlist
but when I comment out the data property, the output shows perfect (but the data binding goes missing)
My array looks like the following
[ { "id": "2015-0152", "text": "2015-0152" }, { "id": "2015-0153", "text": "2015-0153" }, { "id": "2016-0001", "text": "2016-0001" }, { "id": "2016-0002", "text": "2016-0002" }, { "id": "2016-0003", "text": "2016-0003" }, { "id": "2016-0004", "text": "2016-0004" }, { "id": "2016-0005", "text": "2016-0005" }, { "id": "2016-0006", "text": "2016-0006" }, { "id": "2016-0007", "text": "2016-0007" }, { ... }, { "id": "2015-0100", "text": "2015-0100" }, { "id": "2015-0101", "text": "2015-0101" }, { "id": "2015-0080", "text": "2015-0080" }, { "id": "2015-0081", "text": "2015-0081" }, { "id": "2015-0090", "text": "2015-0090" }, { "id": "2015-0102", "text": "2015-0102" }, { "id": "2015-0112", "text": "2015-0112" }, { "id": "2015-0128", "text": "2015-0128" }, { "id": "2015-0136", "text": "2015-0136" } ]
I am really confused about what is going wrong. Any idea?
Select2 version: 3.4.8
This line gives an error: var jsonValue = JSON.parse($(this).attr('data-json')).val());
Should be: var jsonValue = JSON.parse($(this).attr('data-json'));.
Also this line in your question:
i am also customising if the source of the dropdown list is an array
Indicates to me that it might also not be an array. In that cause you should check if it is an array before you pass the data to select2.
EDITED: Another thing that came to my mind was the following.
If you're using data properties for the placeholder I don't think you need to pass the values of those properties to select2 a second time like you do here
placeholder: $(this).attr('data-placeholder'),
minimumInputLength: $(this).attr('data-minimumInputLength'),
Might be that you need to pick one of the two (either pass it along in your settings, or use an attribute). As select2 looks at the data attributes to get a value.
I checked if the above was correct turns out it isn't. It works fine in this fiddle: https://jsfiddle.net/wL7oxbpv/
I think there is something wrong with your array data. Please check that.