I made a question a minutes ago that I could solve but now I'm having another problem with my code, I have an array of objects lstValid[]
and I need each object to be inserted into a table (using a SP) and I though of a way to made it reading documentation but it's not working, maybe it's just a fool mistake but I don't know how to solve it, my mistake is
TypeError: Cannot read properties of undefined (reading 'Id_Oficina')
as you can see, it executes my SP but it says the attribute Id_Oficina
is undefined, do you know why is undefined? why is it reading the array but not the attribute?
Here is the function where I create the objects and insert them into the array:
async function calcWeather() {
const info = await fetch("../json/data.json")
.then(function (response) {
return response.json();
});
for (var i in info) {
const _idOficina = info[i][0].IdOficina;
const lat = info[i][0].latjson;
const long = info[i][0].lonjson;
const base = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${long}&appid=${api_key}&units=metric&lang=sp`;
fetch(base)
.then((responses) => {
return responses.json();
})
.then((data) => {
var myObject = {
Id_Oficina: _idOficina,
Humedad: data.main.humidity,
Nubes: data.clouds.all,
Sensacion: data.main.feels_like,
Temperatura: data.main.temp,
Descripcion: data.weather[0].description,
};
// validation and saving data to array
if (myObject.Temperatura < 99)
lstValid.push(myObject);
});
}
}
and here's the function where I insert into DB:
import { Request } from "tedious";
import { TYPES } from "tedious";
function executeStatement() {
calcWeather();
for (var m = 0; m >= lstValid.length; m++) {
const request = new Request(
"EXEC USP_BI_CSL_insert_reg_RegistroTemperaturaXidOdicina @IdOficina, @Humedad, @Nubes, @Sensacion, @Temperatura, @Descripcion",
function (err) {
if (err) {
console.log("Couldn't insert data: " + err);
}
}
);
request.addParameter("IdOficina", TYPES.SmallInt, lstValid[m].Id_Oficina);
request.addParameter("Humedad", TYPES.SmallInt, lstValid[m].Humedad);
request.addParameter("Nubes", TYPES.SmallInt, lstValid[m].Nubes);
request.addParameter("Sensacion", TYPES.Float, lstValid[m].Sensacion);
request.addParameter("Temperatura", TYPES.Float, lstValid[m].Temperatura);
request.addParameter("Descripcion", TYPES.VarChar, lstValid[m].Descripcion);
request.on("row", function (columns) {
columns.forEach(function (column) {
if (column.value === null) {
console.log("NULL");
} else {
console.log("Product id of inserted item is " + column.value);
}
});
});
connection.execSql(request); // connection.execSql(RequestB);??
}
request.on("requestCompleted", function (rowCount, more) {
connection.close();
});
}
I also tried sending them this way but doesn't work either:
request.addParameter("IdOficina", TYPES.SmallInt, lstValid[m].myObject.Id_Oficina);
The problem seems to be a bad condition at the line of
for (var m = 0; m >= lstValid.length; m++) {
This loop initializes m
with 0 and increments it while it's greater or equal with the number of elements lstValid
has. Since Javascript is a 0-indexed language, lstValid.length
is always an invalid index. Valid indexes fulfill this formula
0 <= valid index < lstValid.length
Since your condition checks whether the index is invalid and only then iterates the loop, it will error out at the first iteration if lstValid
is empty and it will not execute at all when lstValid
is not empty.
for (var m = 0; m < lstValid.length; m++) {
Your error came from the fact that lstValid.length
was 0, m
was 0 and your code attempted to process member fields of the first element of an empty array. Since there was no first element in the speicifc case, it errored out.