I'm new using JSON and I've created an API using Amazon's AWS service to work as a database for my dictionary website.
On the site there is a search bar which when receiving an input goes through my JavaScript to my JSON database to look for the search parameter given. For example "hello" as shown in the code below.
However my problem is that the only thing fetched to my JavaScript is the "hello" and none of the other things.
I know I'm new, but I would appreciate some tips on how i can make it possible using a search parameter get everything shown below.
[
{
"word": "hello",
"phonetic": "həˈləʊ",
"phonetics": [
{
"text": "həˈləʊ",
"audio": "//ssl.gstatic.com/dictionary/static/sounds/20200429/hello--_gb_1.mp3"
},
{
"text": "hɛˈləʊ"
}
],
"origin": "early 19th century: variant of earlier hollo ; related to holla.",
"meanings": [
{
"partOfSpeech": "exclamation",
"definitions": [
{
"definition": "used as a greeting or to begin a phone conversation.",
"example": "hello there, Katie!"
}
]
}
]
}
]
You can use filter to search through the array for a string matching the word.
let data = [
{
"word": "hello",
"phonetic": "həˈləʊ",
"phonetics": [
{
"text": "həˈləʊ",
"audio": "//ssl.gstatic.com/dictionary/static/sounds/20200429/hello--_gb_1.mp3"
},
{
"text": "hɛˈləʊ"
}
],
"origin": "early 19th century: variant of earlier hollo ; related to holla.",
"meanings": [
{
"partOfSpeech": "exclamation",
"definitions": [
{
"definition": "used as a greeting or to begin a phone conversation.",
"example": "hello there, Katie!"
}
]
}
]
},
{
"word": "TEST",
"phonetic": "həˈləʊ",
"phonetics": [
{
"text": "həˈləʊ",
"audio": "//ssl.gstatic.com/dictionary/static/sounds/20200429/hello--_gb_1.mp3"
},
{
"text": "hɛˈləʊ"
}
],
"origin": "early 19th century: variant of earlier hollo ; related to holla.",
"meanings": [
{
"partOfSpeech": "exclamation",
"definitions": [
{
"definition": "used as a greeting or to begin a phone conversation.",
"example": "hello there, Katie!"
}
]
}
]
}
]
let search = "HELLO";
let found = data.filter((row) => {
return (row.word.toLowerCase() == search.toLowerCase())
});
console.log(found)
Related
thank you in advance for reading me. So I have been working in a filte. Right now my filter works, however doesn't do what I want. The current status is. When I select 2 options or more. I get all the values inside the data that contains either optionA oder optionB.
See my example data below:
{
"_uid": "1",
"body": [
{
"_uid": "2",
"name": "John",
"image": {
"id": 6807178,
"filename": "https://",
"copyright": "",
"fieldtype": "asset",
"is_external_url": false
},
"gewerk": "Project Owner",
"skill": ["vuejs", "react", "symfony"],
"component": "person",
},
{
"_uid": "3",
"name": "Jean",
"image": {
"id": 6807182,
"filename": "https://",
"copyright": "",
"fieldtype": "asset",
"is_external_url": false
},
"gewerk": "UI",
"skill": ["svelte"],
"component": "person",
},
{
"_uid": "4",
"name": "Martha",
"gewerk": "Frontend",
"skill": ["vuejs", "react"],
"component": "person",
},
{
"_uid": "5",
"name": "Tom",
"gewerk": "UI",
"skill": ["svelte", "angular", "vuejs"],
"component": "person",
}
],
}
With that being says when I filter using this example combi(screenshot). I get Martha, Tom and John as a result. When what I actually want is to have only Tom as a result. because only Tom have both criterias together inside his skills data.
This is my current computed function:
filterPersonSkill() {
return this.getComponentPerson.filter((e) =>
e.skill.map((skill) => this.multiValue.includes(skill)).includes(true)
);
}
At the beginning I used includes instead of map and that worked half. Because I was getting the result only if I selected in the same order(in the multiselect) as the array skills was appearing. Example below
filterPersonSkill() {
return this.getComponentPerson.filter((e) =>
e.skill.includes(...this.multiValue)
);
}
Thank in advance for the advice and reading me.
I think, it will be much simpler, if you add checkbox for the user to use "exact" filtering, i.e. results which include only selected tags.
With such a checkbox you can do something like this:
// your vue component
export default {
data() {
return {
exactMatch: true,
}
},
methods: {
filterPersonSkillExactMatch() {
const result = [];
for (const p of this.getComponentPerson) {
if (p.skill.length === this.multiValue.length
&& this.multiValue.every(val => p.skill.includes(val))) {
result.push(p)
}
}
return result
}
// somewhere in your code (either computed prop or method):
filteredPersons() {
if (exactMatch) {
return this.filterPersonSkillExactMatch()
}
return this.filterPerson()
}
}
}
I'm currently working on a service that returns the following payload:
{
"account1": {
"app1": {
"status": "Online",
"comments": "blah blah",
"events": [
{
"date": "some date",
"generated_by": "some user"
}
]
}
},
"account2": {
"app1": {
"status": "Offline",
"comments": "blah blah bleh",
"events": [
{
"date": "some date",
"generated_by": "some user"
}
]
},
"app2": {
"status": "Online",
"comments": "blah blah",
"events": [
{
"date": "some date",
"generated_by": "some user"
}
]
}
}
}
I'm trying to render a table with the following fields:
-------------------------------
Application | Account | Status
-------------------------------
app1 | account1 | Online
app1 | account2 | Offline
app2 | account2 | Online
Normally this would be easy to do if my payload would be something like a list of objects but I'm kinda stuck here.
I tried to normalize this payload by extracting each of the fields and creating a new payload by doing something like the following:
const extractAccountNumber = Object.values(payload).map(account => ({account: account}))
which would return:
[
{
"account": "account1"
},
{
"account": "account2"
}
]
I wanted to move on to app name the same way and once I get all my fields I would merge the payload. This has proven to be super cumbersome and I'm sure there is a better, more efficient way to achieve this which I'm probably missing. Any feedback would help me a ton to understand how this can be achieved using javascript with or without lodash.
Iterating by first level and then by second level:
table = [];
for (accountName in apiResponse) {
account = apiResponse[accountName];
for (appName in account) {
app = account[appName];
table.push({
application: appName,
account: accountName,
status: app.status,
});
}
}
Then table is something like this:
[
{
"application": "app1",
"account": "account1",
"status": "Online"
},
{
"application": "app1",
"account": "account2",
"status": "Offline"
},
{
"application": "app2",
"account": "account2",
"status": "Online"
}
]
Can try something like
Object.entries(o).map(([accountName, value]) => ({
account: accountName,
apps: Object.entries(value)
.map(([appName, value]) => ({name: appName, ...value }))
}))
Not sure about structure. Where to put app1 from account2 in that table?
I am trying to gain access within the last array of the json file and return the value from the "data" array of the json file and put it into the choiceSelection array. However, on my local host, it returns an undefined value and the images would not load. Can anyone help me out? I apologise if I haven't clearly explained my problem/logic and so please ask me for more details, if you're not sure. Thanks!
javascript code
$.getJSON('data.json', function(json) {
if(json[2].data){
for (i = 0; i < json[3].data.length; i++) {
choiceSelection[i] = new Array;
choiceSelection[i][0] = json[2].data[i].question;
choiceSelection[i][1] = json[2].data[i].correctChoice;
choiceSelection[i][2] = json[2].data[i].choice1;
choiceSelection[i][3] = json[2].data[i].choice2;
}
// choiceSelection.length = choiceSelection.length;
displayQuestion();
console.log(json[2]);
}
})
json file
[
{
"name": "match numbers 1",
"template": "matching",
"data": [
[
"six",
"Images/Number6.jpg"
],
[
"eight",
"Images/Number8.jpg"
],
[
"nine",
"Images/Number9.jpg"
]
]
},
{
"name": "order numbers 1",
"template": "ordering",
"data": [
[
"Images/Number6.jpg"
],
[
"Images/Number8.jpg"
],
[
"Images/Number9.jpg"
]
]
},
{
"name": "animal",
"template": "picture game",
"data": [
{
"question": "Where is the cat?",
"correctChoice": "Images/5cats.jpg",
"choice1": "Images/squirrel.png",
"choice2": "Images/beagle.png"
},
{
"question": "Where is the cat?",
"correctChoice": "Images/5cats.jpg",
"choice1": "Images/squirrel.png",
"choice2": "Images/beagle.png"
}
]
}
]
Edit 1: change json[i] to json[2].data. Still undefined
Edit 2: changed json[2].data. to json[2].data[i] and used json[3].data.length in the for statement. It works perfectly now. Thank you everyone for the help!:)
You could take the hassle out of your code and use some ES6 destructuring to get at your data more easily.
const json = '[{"name":"match numbers 1","template":"matching","data":[["six","Images/Number6.jpg"],["eight","Images/Number8.jpg"],["nine","Images/Number9.jpg"]]},{"name":"order numbers 1","template":"ordering","data":[["Images/Number6.jpg"],["Images/Number8.jpg"],["Images/Number9.jpg"]]},{"name":"animal","template":"picture game","data":[{"question":"Where is the cat?","correctChoice":"Images/5cats.jpg","choice1":"Images/squirrel.png","choice2":"Images/beagle.png"},{"question":"Where is the cat?","correctChoice":"Images/5cats.jpg","choice1":"Images/squirrel.png","choice2":"Images/beagle.png"}]}]'
function getJSON(endpoint, callback) {
setTimeout(() => callback(JSON.parse(json)), 1000);
}
// grab the third object from the response data
getJSON('data.json', function([ ,,obj ]) {
// grab the data array from that object but relabel it
// `choiceSelection
const { data: choiceSelection } = obj;
// then use the object property keys to get access
// to the data instead of indexes. Much easier.
console.log(choiceSelection[0].question);
console.log(choiceSelection[1].question);
});
I'm wondering how I can compare arrays of (nested) objects in Mongoose.
Considering the data below, I would like to get results when the name properties match. Could anyone help me with this?
Organisation.find( {
$or: [
{ "category_list": { $in: cat_list } },
{ "place_topics.data": { $in: place_tops } }
]
}
)
Let's say that this is the data stored in my MongoDB:
"category_list": [
{
"id": "197750126917541",
"name": "Pool & Billiard Hall"
},
{
"id": "197871390225897",
"name": "Cafe"
},
{
"id": "218693881483234",
"name": "Pub"
}
],
"place_topics": {
"data": [
{
"name": "Pool & Billiard Hall",
"id": "197750126917541"
},
{
"name": "Pub",
"id": "218693881483234"
}
]
}
And let's say that these are the arrays I want to compare against (almost the same data):
let cat_list = [
{
"id": "197750126917541",
"name": "Pool & Billiard Hall"
},
{
"id": "197871390225897",
"name": "Cafe"
},
{
"id": "218693881483234",
"name": "Pub"
}
]
let place_tops = [
{
"name": "Pool & Billiard Hall",
"id": "197750126917541"
},
{
"name": "Pub",
"id": "218693881483234"
}
]
When there are "multiple conditions" required for each array element is when you actually use $elemMatch, and in fact "need to" otherwise you don't match the correct element.
So to apply multiple conditions, you would rather make an array of conditions for $or instead of shortcuts with $in:
Organizations.find({
"$or": [].concat(
cat_list.map( c => ({ "category_list": { "$elemMatch": c } }) ),
place_tops.map( p => ({ "place_topics": { "$elemMatch": p } }) )
)
})
However, if you take a step back and think logically about it, you actually named one of the properties "id". This would generally imply in all good practice that the value is in fact ""unique".
Therefore, all you really should need to do is simply extract those values and stick with the original query form:
Organizations.find({
"$or": [
{ "category_list.id": { "$in": cat_list.map(c => c.id) } },
{ "place_topics.id": { "$in": place_tops.map(p => p.id) } }
]
})
So simply mapping both the values and the property to "match" onto the "id" value instead. This is a simple "dot notation" form that generally suffices when you have one condition per array element to test/match.
That is generally the most logical approach given the data, and you should apply which one of these actually suits the data conditions you need. For "multiple" use $elemMatch. But if you don't need multiple because there is a singular match, then simply do the singular match
I'm very new to elasticsearch and the documentation really just confuses me so please bear with me a little bit here.
I have an index called zproducts and under it a type called item which is mapped looks somewhat like this:
{
"item_name" : "Product A",
"category_ids" : [ "id1", "id2" ]
},
{
"item_name" : "Product B",
"category_ids" : [ "id1" ]
},
{
"item_name" : "Product C",
"category_ids" : [ "id2" ]
}
I want to be able to query for items that match at least one of the of the categories. ie. querying for id2 will return products A and C.
It would seem that I have the exact same problem that this guy had.
But the solution suggested there just doesn't work for me.
This is my current query:
/zproducts/items/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"category_ids": "id2"
}
}
]
}
}
}
Subsequent test query:
{
"query": {
"filtered": {
"filter": {
"term": {
"category_ids": "id2"
}
}
}
}
}
Both queries return ALL the items on store and not just the ones I'm trying to query for.
There was also the original query which, for some reason, used to work but stopped working altogether.
{
"query": {
"bool": {
"must": [
{
"match": {
"category_ids": {
"query": "id2",
"operator": "or"
}
}
}
]
}
}
}
So what am I doing wrong here? Can anyone please shed some light?
This query:
{
"query": {
"filtered": {
"filter": {
"term": {
"category_ids": "id2"
}
}
}
}
}
is correct. Make sure you are making your request as POST /zproducts/items/_search, rather than GET /zproducts/items/_search - getting all documents in an index back for a query is a good hint that the query body is being ignored, which is a good hint that you're using GET; many clients will not send a request body with a GET request, which ES interprets as a blank query.