GOOGLE ADS

Montag, 18. April 2022

TypeError: Eigenschaften von undefined (Lesen von 'location') in res.redirect können nicht gelesen werden

Ich habe die folgende Funktion, um ein Objekt aus einer Datenbank abzurufen und eine URL zu extrahieren:

async redirect(id: string, redirectFunction: Function) {
if (!IdExists(id)) {
throw new Error(`ID ${id} does not exist.`);
}
const redirectLocation: string = await prisma.url.findUnique({
where: { uniqueId: id },
select: { url: true },
}).then((data) => {
return data?.url!;
});
redirectFunction('http://' + redirectLocation);
}

Die Funktion wird im folgenden Codeabschnitt aufgerufen:

app.get('/:id', async (req, res) => {
try {
redirectController.redirect(req.params.id, res.redirect);
} catch (error) {
console.error(error);
}
});

Ich bekomme jedoch die TypeError: Cannot read properties of undefined (reading 'location'), ich sehe, dass der Fehler mit der res.redirectMethode zusammenhängt. Wenn ich es jedoch console.logzum Debuggen durch ersetze, wird die URL richtig angezeigt. Was kann diesen Fehler verursachen?


Lösung des Problems

Diese Codezeile:

redirectController.redirect(req.params.id, res.redirect);

Übergibt res.redirect(eine Funktionsreferenz) als zweites Argument, aber alles, was übergeben wird, ist nur die Funktion, sodass die resverloren geht, wenn Sie später versuchen, sie aufzurufen. Das führt dazu, dass die Methode bei der Ausführung einen falschen thisWert hat und viele Dinge schief gehen.

Sie können das auf verschiedene Arten beheben. Einmal so ist mit .bind():

redirectController.redirect(req.params.id, res.redirect.bind(res));

.bind()erstellt eine kleine Stub-Funktion, die sich den Wert von merkt, ressodass die Stub-Funktion beim Aufruf mit der richtigen Referenz aufgerufen wird resund somit der thisWert innerhalb der Funktion korrekt ist.

Eine andere Möglichkeit, dies zu lösen, besteht darin, eine eigene kleine Stub-Funktion zu erstellen:

redirectController.redirect(req.params.id, (...args) => {
res.redirect(...args);
});

Wenn es Ihre Stub-Funktion aufruft, rufen Sie res.redirect()es richtig auf und übergeben es mit allen Argumenten, mit denen der Controller Ihre Stub-Funktion aufgerufen hat.

Als kleine Demonstration können Sie diesen Effekt hier sehen:


const obj = {
greeting: "Hello",
talk: function() {
if (this && this.greeting) {
console.log(`this.greeting is "${this.greeting}"`);
} else {
console.log("value of this is wrong");
}
}
}
console.log("calling as obj.talk()");
obj.talk(); // works
console.log("-------------------------");
// function we pass a method to and then call that method
function callTalk(fn) {
fn();
}
console.log("calling by passing method to another function");
callTalk(obj.talk); // doesn't work
// call it using.bind()
console.log("-------------------------");
console.log("calling using.bind()");
callTalk(obj.talk.bind(obj)); // works

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...