2016-11-08 7 views
1

Ich bin neu in Express.Express Router.use in Middleware

Ich versuche, eine Anfrage nach einem Wert in der DB zu routen. Dazu rufe ich eine Servicefunktion an. Routing funktioniert erfolgreich, aber ich verliere das Anfrageobjekt. Ich habe versucht, die Anforderung an den Dienst zu übergeben, aber es hat nicht funktioniert.

Jede Hilfe, die zeigt, wie dies zu tun wäre, wäre nett.

Hier ist mein Codeblock.

var companyService = require("services/companyService"); 
router.use('/', function (req, res, next) { 
companyService.isCompanyOnline(req.body.companyCode).then(function (company) { 
    if (company) { 
     router.use('/', require("api/controllers/online")); 
    } 
    else { 
     router.use('/', require("api/controllers/offline")); 
    } 
}); 
next(); 
}); 

module.exports = router; 

Services.companyService:

function isCompanyOnline(code) { 
var deferred = Q.defer(); 
companies.findOne({ companyCode: code }, function (err, company) { 
    if (err) deferred.reject(err.name + ': ' + err.message); 
    //if (err) throw err; 
    if (company) { 
     // return company online parameter 
     deferred.resolve(company.isOnline); 
    } else { 
     // company not found 
     deferred.resolve(); 
    } 
}); 
return deferred.promise; 
} 
+0

** Wo ** sind Sie:

app.use('/api/online', require("api/controllers/online")); app.use('/api/offline', require("api/controllers/offline")); 

dann die URL im Router ändern das 'req'-Objekt verlieren? Oder besser: wo versuchst du auf das 'req' Objekt zuzugreifen? – tmslnz

+0

@ tmslnz in 'api/controllers/online' oder' api/controllers/online' Routen. –

+0

Na dann ... weg zu antworten – tmslnz

Antwort

1

Sie verlieren das Request-Objekt, weil Sie es nicht überall sind vorbei.

Ich glaube, Ihr Hauptproblem hier ist die Tatsache, dass Sie drei Route Handler Registrierung auf dem gleichen Pfad / haben. Wenn ich mich nicht irre, werden sie alle in der Reihenfolge aufgerufen, in der sie hinzugefügt werden. Aber die Reihenfolge in Ihrem hängt von der if Sie setzen die router.use() Anrufe. Es ist also unberechenbar und wird wahrscheinlich nicht wie erwartet funktionieren. Sobald sie registriert sind, bleiben sie im Middleware-Stack, bis Sie die App neu starten.

Ich schlage vor, Sie Refactoring die Online-/Offline-Logik in einem Ort zu haben, oder registrieren Sie alle Ihre Middle einmal an, so dass Sie wissen in welcher Reihenfolge sie aufgerufen werden, und verwenden Sie next() entsprechend.

Auf einer anderen Anmerkung, wenn Sie ein Argument zu require d Module übergeben wollen, dies tun:

ändern api/controllers/online und die anderen, ein Argument zu akzeptieren, und gibt die Handler-Funktion, die Sie vorbei sind.

// your code in api/controllers/online and offline 

module.exports = function (req) { 
    // now you have req available in-scope here 
    function yourFunctionThatNeedsReq (req) { 
     // do stuff with req 
    } 
    return yourFunctionThatNeedsReq; 
}; 

Dann aktualisieren Sie Ihre require wie so. Beachten Sie die …(req).

router.use('/', require("api/controllers/online")(req)); 
+0

Vielen Dank es funktioniert :) –

+0

Das letzte Bit wird nicht funktionieren. Sie rufen die Funktion zur Deklarationszeit auf, wenn noch keine Anfrage vorliegt. Wenn Sie nur: app.use ('/', require ('./ api/controllers/online')), erhalten Sie den von Ihnen beschriebenen Effekt – Paul

+0

@Paul Nicht zu sicher, dass Sie richtig sind ... 'erfordern (...) 'gibt eine" factory "zurück," factory (req) "gibt den Routen-Handler mit dem von der Factory übergebenen Request-Objekt zurück.- Außerdem scheint es für das OP funktioniert zu haben. – tmslnz

0

Meine Lösung:

Zunächst definieren Routen:

if (req.body.companyInfo.isOnline) { 
     req.url = '/online' + req.url + '/' + req.body.companyInfo.companyPath; 
     next(); 
    } 
    else { 
     req.url = '/offline' + req.url + '/' + req.body.companyInfo.companyPath; 
     next(); 
    } 
Verwandte Themen