Vue and Javascript API/Object/Array manipulation for searching values - javascript

Edit to clarify:I have an object from an API response that I get using the mounted function, data is saved not displayed yet. I need to be able to filter that data by allowing a user to input text in an input box before showing it on the page, then find where that keyword was used in a specific key value(name). Then show the results on a page but include other key/value pairs from the api array. This is what the api response looks like:
class: (...)
facets: (...)
numberFound: (...)
results: Array(202)
[0 … 99]
0:
class: "SearchResult"
contentGuid: "7f19462f-6c25-43a9-bdb5-479f5f42fbde"
dateUpdated: "2018-03-27T16:46:31Z"
description: "Converting a Word Document to Adobe Acrobat PDF Learning Services Converting a Word Document to Adobe Acrobat PDF Enterprise Converting a Word Document to Adobe Acrobat PDF / Reference ..."
document: Object
documentGuid: "035f5c69-d406-4c16-86ca-de12773a0963"
documentId: 154424
documentVersionId: 44043
fileId: 74213
format: "PDF"
id: "Document#1#44043"
isFavorite: false
languages: "English"
name: "Converting a Word Document to Adobe Acrobat PDF"
numberOfIndexedCoobs: 0
numberOfSharedLinks: 1
packageType: "PDF"
previewId: 74213
publicLinkTokens: Array(1)
resourceType: "Other"
score: 0.0054571675
snippets: Object
updatedById: 994
updatedByName: "Michael"
versionName: "3"
For example if someone enters "Adobe" in the search box, I would need to search for the word "adobe" in the name value for the entire object, and only show the ones that have "abobe" somewhere in the name value.
My thought was to get the document name split it, then do an includes() to check for the search term. This works but I can't seem to figure out how to get it all to work together and get the results on the screen, plus get additional information, such as document Id from the original results. this is what I have so far:
async getResults() {
return axios
.get(this.url, {
headers: {
"Content-Type": "application/json",
"Bravais-prod-us-Context": this.getCookie(),
},
})
.then((res) => {
this.search = res.data;
this.search.results.forEach((doc) => {
this.results = doc.document.name
.toLowerCase()
.split(" ")
.includes(this.termSearch.toLowerCase());
console.log(doc.document.name.split(" "));
console.log(this.results);
});
})
.catch((error) => console.log(error));
},
I need to show the original title(some words and acronyms are capitalized) plus the doc id(for url links) and a description, all of this info is in the initial api response.
<div v-for="" v-bind:key="">
{{ ???? }}
</div>
That works in the console but how do I get this back together and on the screen?? Any help is appreciated, not looking for someone else to do my coding, just need some advice.

I would start by diving your logic. At the moment you have a single function that makes an api call and then searches through the results. It would be better suited to have the api call in a separate method so that if the user searches multiple times it doesn't call the api each time. We can easily solve this by adding an extra method that checks if the results object is populated and decides which methods to call.
Casting all strings to lowercase is a good idea to normalize the data. There might be other ways but this works for it's intended purpose. However, splitting a string is unecessary as the includes() method searches through the whole string. See the MDN docs for String.prototype.includes()
To search within an array you can use the filter() method, which will create a new array with all elements that pass the implemented test. See the MDN docs for Array.prototype.filter().
With this in hand, we can write our logic as:
async handleSearch(searchString) {
if (!this.results.length) {
this.getResults()
}
this.searchResults(searchString)
},
async getResults() {
return axios.get(this.url, {
headers: {
"Content-Type": "application/json",
"Bravais-prod-us-Context": this.getCookie(),
},
}).then((res) => {
this.results = res.data.results
}).catch((error) => console.error(error));
},
searchResults(searchString) {
this.filteredResults = this.results.filter(item => {
let name = item.name.toLowerCase();
let searchTerm = searchString.toLowerCase();
return this.name.includes(searchTerm)
})
}
Your input field will call the handleSearch() method, and then you can write you html as such:
<div v-for="result in filteredResults" :key="result.id">
<p>Name: {{result.name}}</p>
<p>Description: {{result.description}}</p>
</div>

Related

React json list

I hope I can explain the question clearly. I need to create a few categories in category with <input type="checkbox"/>. Can you help how do it
{
"properties":{
"category":[
"0" : "category-1",
"1" : "category-2"
],
"image": "https://link...",
...
}
}
now I can only add one value at a time, but I need a lot
{
"properties":{
"category": "category-1",
"image": "https://link...",
...
}
}
const handleSubmit = (e) =>{
e.preventDefault();
const movie = {id, category, title, poster, rating, year, video, trailer, description};
fetch('http://localhost:8000/movies', {
method: 'POST',
headers: {"Content-Type" : "application/json" },
body: JSON.stringify(movie)
}).then(() => {
alert('Успешно добавился фильм!');
})
}
So if im understanding you correctly, you want to add multiple categories to the body of a POST endpoint? As long as your api handles an array for the “category”, then its pretty easy! But first, there are some things I see in your code:
In javascript, you don’t explicitly write the index of an array. You just write the item, for
example

const listOfStrings = [“string 1”, “string 2”]
const listOfObj = [{name: ‘Aj”}, {name: ‘bj’}]
It seems like you are implicitly passing in the properties for your “movie” object, just make sure that each property is defined somewhere above.
Now on to your question! What you want to do is the following:
Create a list of categories, make sure they match whatever the backend is expecting
create a state to track the selected categories
map through the array and render an input for each
assign each input props based on its indexed category
create a function that updates the selected state with a new category or a category removed
The key principles you'll need to research if youre unfamiliar with this are:
Javascript: map, filter
React: JSX,
Rendering lists
hooks (useState)
Code Example: https://codesandbox.io/s/jolly-moon-fbhs7c?file=/src/App.js

Associating xxxx_id with xxxx.id

I am running into a problem where when I submit a "property listing" I get this response:
{"owner_id":"Batman","address":"test","state":"test","sale_price":"test"}
The thing is "owner_id" is supposed to equal or associate with owner's id in a different table/JSON file (e.g owner_id = owner.id), not a string in this case which is why the object is not saving on the back-end.
Is anyone in vanilla JavaScript able to show me an example on how to associate owner_id and owner.id?
It'd be more like :
{
owner: {
id: "Batman"
},
address: "test",
state: "test",
sale_price: "test"
}
You should take a look at : https://www.w3schools.com/js/js_json_objects.asp
EDIT: Not sure how you're fetching this data but it seems like you want to handle the response you're getting.
Here is a simple GET request using the fetch api:
fetch('http://example.com/heroes') //this is the path to your source where you're getting your response data
.then((response) => {
return response.json();
//above you return a promise containing your response data
//you can also handle your response before declaring it in a var here
})
.then((myJson) => {
//you have stored your response data as a var myJson
console.log(myJson);
//here you can work your response data in any way you need
// to show an example (not that you would do this) I've provided a owner object that checks if it's property is equal to the incoming data
var owner = {
"id": Batman,
}
if ( myJson.owner_id === owner.id ) {
//do something here
}
});
More info here.

Get URL script content in Node.js with fetch

I'm trying to fetch contents inside a script tag from a url using node-fetch and then trying to json parse the data but i keep getting a return undefined.
I'm trying to get the content from the variable game from the html below and then stringify and then parse the json but it returns undefined.
Page html:
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>Document Title</title>
</head>
<body>
<div id="welcome-div">
<p>Welcome to the my website</p>
</div>
<script>
var game = new Game({
stage: "prod",
servers: {
v32306117: {
id: "v32306117",
name: "name #1",
hostname: "hostname1",
port: 80,
},
v32306125: {
id: "v32306125",
name: "name #2",
hostname: "hostname2",
port: 80,
}
},
userGroup: 0
});
game.init(function() {
game.assetManager.load([{
"name": "\/asset\/image\/map\/grass.png",
"url": "\/asset\/image\/map\/grass.png"
}]);
game.debug.init();
game.run();
});
</script>
</body>
</html>
Fetch function:
const fetch = require("node-fetch");
async function serversFetch() {
try {
const servers = await fetch("https://get-servers.herokuapp.com/");
const data = await servers.text();
const servers_data = data.substring(
data.lastIndexOf("var game =") + 20,
data.lastIndexOf("game.init") - 10
);
return JSON.stringify(servers_data);
} catch (error) {
console.log(error);
}
}
(async () => {
const data = await serversFetch();
console.log('data', data);
const info = JSON.parse(data);
console.log('info', info.servers); // returns undefined
})()
if i console log info.servers it comes back undefined but if i console log just info it logs the output below.
info {
stage: "prod",
servers: {
v32306117: {
id: "v32306117",
name: "name #1",
hostname: "hostname1",
port: 80,
},
v32306125: {
id: "v32306125",
name: "name #2",
hostname: "hostname2",
port: 80,
}
},
userGroup: 0
}
The issue you are running into is because JSON.stringify only works on JavaScript objects and servers_data is a string. What this results in is info being a string later on and that's why console.log(info.servers) logs undefined. When you checked console.log(info), it only had the appearance of working correctly since it was logging the string value of the object. You could test this by performing console.log(typeof info) and you'll see it's of type string.
What you are looking for is to have servers_data be a valid JSON string instead of being a string of a JavaScript object (which is missing all those double-quotes around object property names which JSON requires). The first option might be to brute force it and replace those properties with properties wrapped in double-quotes, i.e. servers: for "servers:" (the colon is included to make it more unique, but it's still not bulletproof). That doesn't help you with properties like v32306117 which are likely unique and can't be replaced easily using the brute force replacement which is looking for known properties.
The next option would likely be to create a parser for the string which could parse it into an abstract syntax tree (AST) for JavaScript. You could then map that to the AST of JSON easily and then reform it as a string using a parser which understands the AST of JSON. Most parsers which use ASTs can parse a string to an AST and create a string from an AST. These parsers are often written using a recursive descent parser. Though this is a great exercise for programmers, you could likely find some libraries which implement AST parsers for JavaScript and JSON. Also, it's a bit of overkill with what you are trying to accomplish.
The final option which I think would be the easiest to implement and easiest to maintain would be to use JSON5, which is a superset of JSON. Using JSON5.parse, you could parse servers_data as is and not have to worry about JSON formatting. This is because JSON5 accepts properties without the double-quotes and is much more lenient about the formatting (double-quotes vs single-quotes, etc.).

Use an input data variable as a key getting Zapier results (custom integration)

I'm having an issue with building a private Zapier integration since Zapier can only use arrays as outputs instead of objects. The array I needs to call is nested 2 levels into my API results, and the key it needs to call is a variable unique to the task called (but I can I can make it part of the input data).
So to get the correct array, the javascript would need to be something like "return results.custom_field_values[bundle.inputData.id]", but I can't find a way to get the input data variable to be accepted in the results like.
Is this possible? I couldn't find a solution in the support documentation.
Here is the call I'm making:
const options = {
url: `https://api.mavenlink.com/api/v1/custom_field_values.json?subject_type=story&with_subject_id=${bundle.inputData.subject_id}& custom_field_name=Active Assignee`,
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${bundle.authData.access_token}`,
'Accept': 'application/json'
},
params: {
'subject_id': bundle.inputData.with_subject_id,
'display_value': 'Active Assignee'
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = z.JSON.parse(response.content);
// You can do any parsing you need for results here before returning them
return results.custom_field_values[bundle.inputData.id];
});
Here is my result when I call just results.custom_field_values:
{
"233451615": {
"can_edit": true,
"subject_type": "story",
"account_id": 4150797,
"subject_id": 385046515,
"updated_at": "2019-03-18T13:54:28-07:00",
"value": [
638945
],
"display_value": "Irma Davila",
"setter_id": "10976265",
"custom_field_id": "181017",
"created_at": "2019-03-05T07:00:15-08:00",
"custom_field_name": "Active Assignee",
"type": "single",
"id": "233451615"
}
}
What I'm trying to do is call only the array within the object that in this case is "233451615" (It's the same as the ID). However, even though the object is different every time, it can be provided as a variable via the input.
Thanks to anyone willing to help!
You need to use [] notation Ref
Change this
"return results.custom_field_values.{bundle.inputData.id}"
to this
"return results.custom_field_values[bundle.inputData.id]"
Have you tried bracket notation instead of dot notation?
something like this :
results.custom_field_values[{bundle.inputData.id}]
Also make sure that bundle.inputData.id is the correct value.

Function getting firebase object returns hard to use object

What I am trying to do
I am creating a social media app with react native and firebase. I am trying to call a function, and have that function return a list of posts from off of my server.
Problem
Using the return method on a firebase query gives me a hard to use object array:
Array [
Object {
"-L2mDBZ6gqY6ANJD6rg1": Object {
//...
},
},
]
I don't like how there is an object inside of an object, and the whole thing is very hard to work with. I created a list inside my app and named it items, and when pushing all of the values to that, I got a much easier to work with object:
Array [
Object {
//...
"key": "-L2mDBZ6gqY6ANJD6rg1",
},
]
This object is also a lot nicer to use because the key is not the name of the object, but inside of it.
I would just return the array I made, but that returns as undefined.
My question
In a function, how can I return an array I created using a firebase query? (to get the objects of an array)
My Code
runQ(group){
var items = [];
//I am returning the entire firebase query...
return firebase.database().ref('posts/'+group).orderByKey().once ('value', (snap) => {
snap.forEach ( (child) => {
items.push({
//post contents
});
});
console.log(items)
//... but all I want to return is the items array. This returns undefined though.
})
}
Please let me know if I'm getting your question correctly. So, the posts table in database looks like this right now:
And you want to return these posts in this manner:
[
{
"key": "-L1ELDwqJqm17iBI4UZu",
"message": "post 1"
},
{
"key": "-L1ELOuuf9hOdydnI3HU",
"message": "post 2"
},
{
"key": "-L1ELqFi7X9lm6ssOd5d",
"message": "post 3"
},
{
"key": "-L1EMH-Co64-RAQ1-AvU",
"message": "post 4"
}
...
]
Is this correct? If so, here's what you're suppose to do:
var items = [];
firebase.database().ref('posts').orderByKey().once('value', (snapshot) => {
snapshot.forEach((child) => {
// 'key' might not be a part of the post, if you do want to
// include the key as well, then use this code instead
//
// const post = child.val();
// const key = child.key;
// items.push({ ...post, key });
//
// Otherwise, the following line is enough
items.push(child.val());
});
// Then, do something with the 'items' array here
})
.catch(() => { });
Off the topics here: I see that you're using firebase.database().... to fetch posts from the database, are you using cloud functions or you're fetching those posts in your App, using users' devices to do so? If it's the latter, you probably would rather use cloud functions and pagination to fetch posts, mainly because of 2 reasons:
There might be too many posts to fetch at one time
This causes security issues, because you're allowing every device to connect to your database (you'd have to come up with real good security rules to keep your database safe)

Categories