Hice un objeto simple llamado 'clima' que tiene un método dentro. El objeto meteorológico debe tener tres métodos.
getWeather: obtenga datos meteorológicos, que es el método getWeather, que utiliza la API xmlhttprequest para obtener información meteorológica y pasar los datos meteorológicos, que es xhr.responseText, a otro método (devolución de llamada) para que, en el segundo método, pueda desestructurar los datos meteorológicos y guardarlos en variables .
devolución de llamada: como se explicó, el método de devolución de llamada debe obtener datos del método getWeather. Sin embargo, aparece un error que dice "Error de tipo no detectado: la devolución de llamada no es una función en XMLHttpRequest.xhr.onload" .
la búsqueda está ahí para pasar la función al método getWeather cuando se activa eventListener cuando se hace clic.
En resumen, solo quiero extraer datos del método getWeather y pasar esos datos a la devolución de llamada
Quiero hacer esto sin fetch.then o sin prometer mi xmlhttprequest.
let weather = { apiKey:'dcaa6d5ea6bc87524fd5e38257edabba', city: 'montreal', getWeather: function (city, callBack) { const xhr = new XMLHttpRequest(); xhr.open( 'get' ,`https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${this.apiKey}` , true) xhr.onload = function () { if (xhr.status >= 200 && xhr.status < 300) { const weatherData = JSON.parse(xhr.responseText); // console.log(weatherData); console.log(weatherData); callBack() } } xhr.send() }, callback: function () { console.log('weatherData') }, search: function () { this.getWeather('new york') }};
document .querySelector('.button') .addEventListener('click', () => weather.search())El error se debe a que el motor de JavaScript no puede resolver cuál es el valor del parámetro de callback de llamada de getWeather cuando se invoca en weather.search y también cuando la función que asignó a xhr.onload finalmente se invoca cuando la solicitud se completa correctamente.
Hay varias formas de asegurarse de que el parámetro o la variable de devolución de llamada se resuelva correctamente en el método de devolución de llamada del objeto meteorológico, que parece ser lo que pretendía.
Uno: al proporcionar el argumento para el segundo parámetro de getWeather: callback de llamada o al usar la sintaxis de valor de parámetro predeterminado para darle a ese parámetro un valor de respaldo si no se proporciona.
let weather = { apiKey:'dcaa6d5ea6bc87524fd5e38257edabba', city: 'montreal', getWeather: function (city, callback = this.callback) { const xhr = new XMLHttpRequest(); xhr.open( 'get', 'https://randomuser.me/api/' // There is a 401 error interpreted as unauthorized for the api below, thus why the above api is used to test // ,`https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${this.apiKey}` , true) xhr.onload = function () { if (xhr.status >= 200 && xhr.status < 300) { const weatherData = JSON.parse(xhr.responseText); callback(weatherData) } } xhr.send() }, callback: function (weatherData) { console.log(weatherData) }, search: function () { this.getWeather('new york', this.callback); // the below also works //this.getWeather('new york'); } }Dos: mediante el suministro entusiasta de algunos o todos los argumentos de una función antes de invocarla a través del método de cierre provisto por el motor llamado vinculación en el prototipo de función.
En su caso, se puede proporcionar un solo parámetro a getWeather : que es city , mientras que se proporciona un nuevo parámetro a la función asignada a xhr.onload , y se puede proporcionar un argumento sólido de this.callback mediante Function.prototype.bind .
let weather = { apiKey:'dcaa6d5ea6bc87524fd5e38257edabba', city: 'montreal', getWeather: function (city) { const xhr = new XMLHttpRequest(); xhr.open( 'get', 'https://randomuser.me/api/' // There is a 401 error interpreted as unauthorized for the api below, thus why the above api is used to test // ,`https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${this.apiKey}` , true) xhr.onload = function (xhrCallback) { if (xhr.status >= 200 && xhr.status < 300) { const weatherData = JSON.parse(xhr.responseText); xhrCallback(weatherData) } }.bind(null, this.callback) xhr.send() }, callback: function (weatherData) { console.log(weatherData) }, search: function () { this.getWeather('new york') } } Finalmente, tenga en cuenta que tuve que usar una API de randomuser porque la API en su pregunta no está autorizando y puede cambiarla según sea necesario.