函数参数未在回调中定义

Function parameter is not defined in callback

我正在尝试获取用户的位置并使用它来获取城市。 我不知道为什么,但是当我调用 query 函数时,city 参数有一些值,但它没有反映在回调函数的 if 条件中。 但是,如果我将 If 条件中的 city 变量替换为常见的 String 回调函数,则效果很好。 数据变量是对象数组

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
}

你必须 return false 在过滤器中,如果它没有通过你的条件 - 因此,最好只写:

return val['District'] === city && val['Specialties'].toLowerCase().indexOf("eye") != -1

在这种情况下,return 值将是 Booleantrue 如果通过,false 如果没有)。

此外,data 变量未在函数中定义。最好将其作为参数传递。

还有:data 数组中的 objects 有一个名为 Specialities 的键,但您过滤的是 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)

编辑:避免打字

有一种方法可以避免像您的代码中那样的拼写错误:使用 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)

这样您就可以选择更简单的单词而不是复杂的字符串。

编辑 2

此外,如果您对函数的设置稍有不同,则可以更新此解决方案:

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)

如果多次过滤特定类型医院的数据源,此解决方案似乎会好一些。当您通过一个一个地传递参数来创建函数时,它们会被缓存(通过 V8),因此使用它们会变得更快。 (至少理论上是这样。)