I am trying to get the location of the user and using that I am trying to get the city.
I don't why but when I call the query
function, the city parameter is having some value but it is not reflected in the callback function's if condition.
However, if I replace the city variable in the If condition with the common String callback function works fine.
the data variable is the array of objects
var data = [{ District: "surat", Specialties: "eye" }, ...., {}];
getLocation();
function getLocation() {
var lat = "";
var lon = "";
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition, showError);
} else {
console.log("denied");
}
}
function showPosition(position) {
console.log("2");
lat = position.coords.latitude;
lon = position.coords.longitude;
console.log(lat);
console.log(lon);
displayLocation(lat, lon);
}
function showError(error) {
switch (error.code) {
case error.PERMISSION_DENIED:
console.log("User denied the request for Geolocation.");
break;
case error.POSITION_UNAVAILABLE:
console.log("Location information is unavailable.");
break;
case error.TIMEOUT:
console.log("The request to get user location timed out.");
break;
case error.UNKNOWN_ERROR:
console.log("An unknown error occurred.");
break;
}
}
async function displayLocation(latitude, longitude) {
let city = "";
var geocoder;
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(latitude, longitude);
await geocoder.geocode(
{
latLng: latlng,
},
function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log(results);
if (results[0]) {
var add = results[0].formatted_address;
var value = add.split(",");
count = value.length;
country = value[count - 1];
state = value[count - 2];
city = value[count - 3];
console.log(city);
} else {
console.log("not found");
}
} else {
console.log(status);
}
}
);
await query(city);
}
function query(city) {
console.log(city); // it is printing Correctly
var hospitals = data.filter((val) => {
if (
val["District"] === city &&
val["Specialties"].toLowerCase().indexOf("eye") != -1
) {
return true; //instead of city(parameter) if I put a String(For Example"Boston") it works completely fine.
}
});
console.log(hospitals); //hospital array is empty instead of having some value
}
CodePudding user response:
You have to return false
in the filter, if it is not passing your condition - thus, it is better to just write:
return val['District'] === city && val['Specialties'].toLowerCase().indexOf("eye") != -1
In this case the return value is going to be Boolean
(true
if passes, false
if not).
Also, the data
variable is not defined in the function. It's better to pass it in as an argument.
And also: the objects
in the data
array have a key called Specialities
, but you are filtering for Specialties
const data = [{
District: "city1",
Specialties: "yeseye1",
},
{
District: "city1",
Specialties: "noye1",
},
{
District: "city1",
Specialties: "yeseye2",
},
]
console.log('====== old query ======')
function query(city) {
console.log(city); // it is printing Correctly
var hospitals = data.filter((val) => {
if (val['District'] === city && val['Specialties'].toLowerCase().indexOf("eye") != -1) {
return true; //instead of city(parameter) if I put a String(For Example"Boston") it works completely fine.
}
});
}
const a = query("city1")
console.log(a)
console.log('====== newQuery ======')
const newQuery = (city, data) => data.filter((val) => val['District'] === city && val['Specialties'].toLowerCase().indexOf("eye") != -1)
const b = newQuery("city1", data)
console.log(b)
EDIT: AVOIDING TYPOS
There's a way to avoid typos like the one in your code: use constants
:
const DIST = "District"
const SPEC = "Specialities"
const EYE = "eye"
const data = [{
[DIST]: "city1",
[SPEC]: "yeseye1",
},
{
[DIST]: "city1",
[SPEC]: "noye1",
},
{
[DIST]: "city1",
[SPEC]: "yeseye2",
},
]
const newQuery = (city, data) => data.filter((val) => val[DIST] === city && val[SPEC].toLowerCase().indexOf(EYE) != -1)
const b = newQuery("city1", data)
console.log(b)
This way you can choose easier words instead of complicated strings.
EDIT 2
Also, you could update this solution if you'd set up the function(s) a bit differently:
const DIST = "District"
const SPEC = "Specialities"
const EYE = "eye"
const data = [{
[DIST]: "city1",
[SPEC]: "yeseye1",
},
{
[DIST]: "city1",
[SPEC]: "noye1",
},
{
[DIST]: "city1",
[SPEC]: "yeseye2",
},
]
const curriedQuery = (data) => (filterTerm) => (city) => data.filter((val) => val[DIST] === city && val[SPEC].toLowerCase().indexOf(filterTerm) != -1)
const queryWithCityList = curriedQuery(data) // this sets the list of cities
const queryCityListForEye = queryWithCityList(EYE) // this sets the type of hospitals
const c = queryCityListForEye("city1") // this queries the hospitals in one city -> and gives you the result
console.log(c)
This solution seems a bit better if you filter the data source for a certain type of hospital many times over. As you create functions by passing in arguments one by one they are cached (by V8), so working with them becomes faster. (At least theoretically.)