Getting results of a MongoDB query to use in a select menu - javascript

I'm working on a website that allows you to search for people in a database based on location. Initially, the dropdown menu (select) is populated with provinces that available people are in. I'm trying to use a mongo query to populate that select menu. But when I try to get the values outside the function, it does not work and the select menu turns up empty.
import * as React from "react";
import axios from "axios";
const Locations = () => {
let options = null;
function axiosTest() {
// This is a server link i created that runs a query that returns distinct provinces from the database
const promise = axios.get("/api/v2/people/provinces");
const dataPromise = promise.then(result => result.data).then(data => {console.log(data);return data;});
// The console.log() above displays all the objects that are in the query given by the server link in an array
// e.g. ['British Columbia', 'Alberta', 'Saskatchewan', etc.]
}
var type = axiosTest();
console.log(type); // now it displays it as "undefined"
if (type) {
options = type.map((el) => <option key={el}>{el}</option>);
}
return (
<div
style={{
padding: "16px",
margin: "16px",
}}
>
<form>
<div>
<select>
{
/** This is where we have used our options variable */
options
// and the select menu is shown as blank, because it doesn't have any options to fill it with
}
</select>
</div>
</form>
</div>
);
};
export default Locations;
Can someone please help me get this to work? Is it something to do with Threads and Concurrency? I'm unfortunately rusty at that.

Function axiosTest() does not return anything. You should specify change your code so the function would return the result of DB query. You can also change .then() syntax with async/await so your code would become more readable.
const Locations = async () => {
let options = null;
function axiosTest() {
return axios.get("/api/v2/people/provinces");
}
var type = await axiosTest();
console.log(type);
...
};

Related

How to access state values from a different class in React?

I'm trying to create a search bar that filters out a set of data. The search function I made uses several states to filter results. When the search bar and results page are in the same class, the search function works but what I'm trying to do now is separate the search bar and display the search results on a separate page. Here's the state being set in the SearchBar class.
handleChange = (event) => {
this.setState({
names: event.target.value
})
}
The problem is I have no idea how to get the data stored in the SearchBar class to be displayed on the results page. Here's how I'm filtering the results on the results page.
const filteredData = data.filter(entry => (entry.name === (this.state.names))
This data is being filtered in the Search class but this.state.names is being stored in the SearchBar class. This SearchBar class is being displayed on my header where users can search for whatever they want and after they press search, the results page appears. So how can I take the data stored in the SearchBar class and use it in a different class?
UPDATE: I tried passing in the state to the Search class in the render function but that causes the entire page to just freeze.
render() {
return (
<Search names = {this.state.names} />
)
}
Not sure if I understood correctly but:
You can make a new component to store your data.
Then use this function (or similar) in onChange on that component
const filterData = (e) => {
const valueToCheck = e.target.value
let newArr = []
for(entry of data) {
// do the logic
//push the data you want into an array
newArr.push(entry)
}
setState(newArr)
}
SearchBar should call onSearchResults([...]) callback and then PageResult may accept those results, you need a component that orchestrate all.
const App = () =>{
const [results, setResults] = useState([]);
return (<>
<SearchBar onSearchChange={setResults}/>
{ results.length && <PageResult results={results}/> }
</>)
}
SearchBar will call props.onSearchChange(results) with the filtered data. App component will react to that change and send those results to PageResult component

Intermittently database search and drop down filter self population code does not work - seemingly randomly - cannot find a pattern

I see that someone has given me a minus 1. I am a 55 year old mother who has no experience. I have many skills but this is not one of them. I am absolutely desperate and have bust myself to get this far. If you cannot help, I accept that, but please do not be negative towards me. I am now crying. Some encouragement would be much appreciated.
I have a page which displays items from a database on a repeater. The code searches the items using several drop down filters, which are populated from the database. Intermittently, seemingly randomly (no pattern is emerging despite extensive testing) the code is failing to populate random drop down filters (one or more of the drop down filters show the default settings rather than those self populated from the database). I discovered this by either repeatedly visiting the page or by repeatedly refreshing the page. Often the code works, then every 3 or 4 times, one or more of the drop down filters shows its default settings rather than those self populated from the database (then the next time it goes wrong, it might be the same or a different one or set of filters which do not work)
This is the code. On this page, there are 3 drop down filters but I have several pages like this, each displaying and searching a different database, with up to 10 drop down filters on each page, and they all have this intermittent problem...
import wixData from "wix-data";
$w.onReady(function () {
$w('#iTitle')
$w('#iCounty')
$w('#iGeog')
$w('#dataset1')
$w('#text102')
});
let lastFilterTitle;
let lastFilterCounty;
let lastFilterGeog;
export function iTitle_change(event, $w) {
filter($w('#iTitle').value, lastFilterCounty, lastFilterGeog);
}
export function iCounty_change(event, $w) {
filter(lastFilterTitle, $w('#iCounty').value, lastFilterGeog);
}
export function iGeog_change(event, $w) {
filter(lastFilterTitle, lastFilterCounty, $w('#iGeog').value);
}
function filter(title, county, geog) {
if (lastFilterTitle !== title || lastFilterCounty !== county || lastFilterGeog !== geog) {
let newFilter = wixData.filter();
if (title)
newFilter = newFilter.eq('title', title);
if (county)
newFilter = newFilter.eq('county', county);
if (geog)
newFilter = newFilter.eq('geog', geog);
$w('#dataset1').setFilter(newFilter)
.then(() => {
if ($w('#dataset1').getTotalCount() ===0) {
$w('#text102').show();
}
else {
$w('#text102').hide();
}
})
.catch((err) => {
console.log(err);
});
lastFilterTitle = title;
lastFilterCounty = county;
lastFilterGeog = geog;
}
}
// Run a query that returns all the items in the collection
wixData.query("Psychologists")
// Get the max possible results from the query
.limit(1000)
.ascending("title")
.distinct("title")
.then(results => {
let distinctList = buildOptions(results.items);
// unshift() is like push(), but it prepends an item at the beginning of an array
distinctList.unshift({ "value": '', "label": 'All Psychologists'});
//Call the function that builds the options list from the unique titles
$w("#iTitle").options = distinctList
});
function buildOptions(items) {
return items.map(curr => {
//Use the map method to build the options list in the format {label:uniqueTitle, valueuniqueTitle}
return { label: curr, value: curr };
})
}
// Run a query that returns all the items in the collection
wixData.query("Psychologists")
// Get the max possible results from the query
.limit(1000)
.ascending("county")
.distinct("county")
.then(results => {
let distinctList = buildOptions(results.items);
// unshift() is like push(), but it prepends an item at the beginning of an array
distinctList.unshift({ "value": '', "label": 'All Counties'});
//Call the function that builds the options list from the unique titles
$w("#iCounty").options = distinctList
});
function buildOptions1(items) {
return items.map(curr => {
//Use the map method to build the options list in the format {label:uniqueTitle1, valueuniqueTitle1}
return { label: curr, value: curr };
})
}
// Run a query that returns all the items in the collection
wixData.query("Psychologists")
// Get the max possible results from the query
.limit(1000)
.ascending("geog")
.distinct("geog")
.then(results => {
let distinctList = buildOptions(results.items);
// unshift() is like push(), but it prepends an item at the beginning of an array
distinctList.unshift({ "value": '', "label": 'All Regions'});
//Call the function that builds the options list from the unique titles
$w("#iGeog").options = distinctList
});
function buildOptions2(items) {
return items.map(curr => {
//Use the map method to build the options list in the format {label:uniqueTitle2, valueuniqueTitle2}
return { label: curr, value: curr };
})
}
export function button45_click(event, $w) {
//Add your code for this event here:
filter($w('#iTitle').value='', $w('#iCounty').value='', $w('#iGeog').value='');
}
My experience and knowledge is very limited, so the answer may well be very simple. Any help would be much appreciated as I will have to abandon my project if I can't find a solution.Thank you

Wix guide for creating Related Product list doesn't reload itself onclick

I've followed Wix's guide to create a Related Products area at the bottom of their dynamic product page.
It mostly works as you'd expect. The problem comes when you click on one of the related products and see that the related products list doesn't change to reflect the currently loaded product.
The only way to get the related products list to change is by refreshing the page.
Is there possibly a simple fix for this? Below is their code:
import wixData from 'wix-data';
import wixLocation from 'wix-location';
$w.onReady(function () {
loadRelatedProducts();
});
async function loadRelatedProducts() {
let product = await $w('#productPage1').getProduct();
let relatedProductResults = await Promise.all([
relatedProductsByTable(product),
relatedProductsByPrice(product)
]);
if (relatedProductResults[0].length > 0)
showRelatedProducts(relatedProductResults[0]);
else
showRelatedProducts(relatedProductResults[1]);
}
async function relatedProductsByTable(product) {
let productId = product._id;
// find related products by relation table
let relatedByTable = await Promise.all([
wixData.query('RelatedProducts')
.eq('productA', productId)
.include('productB')
.find(),
wixData.query('RelatedProducts')
.eq('productB', productId)
.include('productA')
.find()
]);
let relatedProducts = [
...relatedByTable[0].items.map(_ => _.productB),
...relatedByTable[1].items.map(_ => _.productA)
];
return relatedProducts;
}
async function relatedProductsByPrice(product) {
let productId = product._id;
// find related products by price
let relatedByPrice = await wixData.query('Stores/Products')
.between('price', product.price * 0.8, product.price * 1.2)
.ne('_id', productId)
.find();
return relatedByPrice.items;
}
function showRelatedProducts(relatedProducts){
if(relatedProducts.length > 0){
relatedProducts.splice(4, relatedProducts.length);
$w('#relatedItemsRepeater').onItemReady(relatedItemReady);
$w("#relatedItemsRepeater").data = relatedProducts;
$w("#relatedItems").expand();
}
else {
$w("#relatedItems").collapse();
}
}
function relatedItemReady($w, product){
$w("#productImage").src = product.mainMedia;
$w("#productName").text = product.name;
$w("#productPrice").text = product.formattedPrice;
$w('#productImage').onClick(() => {
wixLocation.to(product.productPageUrl);
});
}
I suspect the issue is in this all being triggered by the .onReady() event. Unfortunately, I'm not sure how to also make this re-run on another trigger like when the related item itself is clicked.
The page itself does not reload when you click one of the related products. Instead, I believe they are simply rewriting the URL and then updating then re-fetching data from the database.
Indeed, you are correct. The page itself doesn't reload when a related item is selected so a new list of related items is not generated. Actually, at the time this example was published there was no simple way to get around this.
Since then, Wix has exposed the wix-location.onChange() function to take care of this very problem. All you need to do is add the following line:
wixLocation.onChange( () => loadRelatedProducts() );
It probably makes the most sense to add it right before the onReady() or even inside the onReady().

Fail to load the image

Error from the Browser console:
https://static.food2fork.com/pastaallavodkaa870.jpg.jpg 404
Trying to display the image on the browser, I don't know if it is a problem from my code or food2fork end.
My index.js:
// always make sure you have the right directory
// import field
import Search from './models/Search';
// import all the function from the view
import * as searchView from './views/searchView'
import {elements} from './views/base';
/* Global state of the app
- Search obj
- current recipe obj
- shopping list object
- liked recipes
*/
// everytime we reload the app, it will be empty
const state = {}
const controlSearch = async () =>{
// 1) Get the query from the view
const query = searchView.getInput();
if(query){
// 2) new search object and add it to state
state.search = new Search(query); // new instance of the search class
// 3) prepare UI for results
// 4) Search for recipes
await state.search.getResults(); // await this promise then render the result
// 5) render result in the UI, reminder u got hit the search button
searchView.renderResult(state.search.result);
}
}
elements.searchForm.addEventListener('submit', e => {
e.preventDefault();
controlSearch();
});
My Search.js:
// this is the external source simply call its name
import axios from 'axios';
// query and then the search result
// class declarition ES6
export default class Search {
constructor(query){
this.query = query;
}
async getResults(){
// fetch is only gonna work for modern browser
// HTTP request axios
// if you enter the invalid the key it will not work
//key is blurred out for stackoverflow
const key = '------------------------';
// return json
// if we can not access it we are going to use the cors proxy
// const proxy = you can use google to search for cors proxy
try{
const res = await axios(`https://www.food2fork.com/api/search?key=${key}&q=${this.query}`);
this.result = res.data.recipes;
// console.log(this.result);
} catch(error){
alert(error);
}
}
}
My searchView.js:
// if we are in the current folder then it is simply base
import {elements} from './base';
// return the input value from the field
// implicit search automatically return
export const getInput =() => elements.searchInput.value;
const renderRecipe = recipe =>{
const markup = `
<li>
<a class="results__link" href="#${recipe.recipe_id}">
<figure class="results__fig">
<img src="${recipe.image_url}.jpg" alt=${recipe.title}>
</figure>
<div class="results__data">
<h4 class="results__name">${recipe.title}</h4>
<p class="results__author">${recipe.publisher}</p>
</div>
</a>
</li>
`;
// insert the html
elements.searchResList.insertAdjacentHTML('beforeend',markup);
}
export const renderResult = recipes => {
recipes.forEach(renderRecipe);
}
My base.js:
// all the DOM element will be in this class object
export const elements = {
searchForm: document.querySelector('.search'),
searchInput: document.querySelector('.search__field'),
searchResList: document.querySelector('.results__list')
}
I am new to the web-Dev and learning by myself. I hope this is not a bad question. I need a experienced mind to help me take a look at this error, since it is not a syntax or logic error. Thanks a lot and have a great day.
https://static.food2fork.com/pastaallavodkaa870.jpg.jpg
Did you mean to add .jpg.jpg?.. if not then take off the last .jpg
https://static.food2fork.com/pastaallavodkaa870.jpg
Remove the duplicate .jpg and it will work.
https://static.food2fork.com/pastaallavodkaa870.jpg

Ember findRecord and include

I have a component which needs to query a service for homes in a postcode. This is to populate a select dropdown list in response to a user entering a postcode.
So I have
export default Ember.Component.extend({
store: Ember.inject.service(),
actions: {
findHome: function(){
// component declared for promise
var component = this;
var postcode = this.get( 'area.postcode');
var store = this.get('store');
// EITHER...
var x = store.findRecord('postcode', postcode, {include: 'homes'})
.then( function (area) {
component.set( 'homes', area.homes);
});
// OR...
var x = store.findRecord('postcode', postcode, {include: 'homes'})
component.set( 'homes', x.homes );
}
}
});
Anyway,it doesn't work as neither solution has a proper array of homes. How should I be doing this?
I can see Mirage returning the data (postcode and included homes) in response to the findRecord.
In ember-data, relationship return Promises. so in your case you might alter your first option little bit like the below,
store.findRecord('postcode', postcode, {include: 'homes'})
.then( function (area) {
area.get('homes').then((result)=>{ component.set( 'homes',result);
});
});
Remember your second option is wrong, since findRecord return Prmise, so you are setting Prmoise instead of result to homes.

Categories