Unable to attach an res.send(result) in my Nodejs

2020-03-31 23:42发布

问题:

I have made a Nodejs and angular2 app where i need to integrate them to Neo4j app. I am able to hit the Database from my NodeJS code coming from Angular2 but then i am unable to send that data back to angular2 app. If i give

 res.send(result) 

anywhere in my function tmsServer , i get error -->

 inside catch = Error: Can't set headers after they are sent.

Please help. I want to send my data back to angular app.

tmservercontroller.js

   // Require Neo4j
   var neo4j = require('neo4j-driver').v1;

  var path = require('path');
  var logger = require('morgan');
  var bodyParser = require('body-parser');
  var express = require('express');

  var router = express.Router();

   var app = express();


  // Create Driver
   const driver = new neo4j.driver("bolt://localhost:11001", 
   neo4j.auth.basic("neo4j", "Virtuallib1"));



 // //View Engine

   app.set('views', path.join(__dirname, 'views'));

   app.use(logger('dev'));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(express.static(path.join(__dirname, 'public')));



  var session = driver.session();
  var request = require('request');

   var finalResult ;

   router.post('/', tmsServer);
   module.exports = router;


   function tmsServer(req, res) { 

    session
       .run('MATCH (n) RETURN n LIMIT 5')

       .then(function (result){

           result.records.forEach(function(record){
               console.log("record = ", record);
               console.log("result = ", result)
               console.log("1] 
   record._fields[0].properties=",record._fields[0].properties);


                    res.send(result); 
           });


       })


       .catch(function(err){
        console.log("inside catch = "+err);
    })

    res.send('It Works');
    session.close();
   }

neo4j-primary.component.ts

   import { Component, OnInit } from '@angular/core';
   import { Injectable } from '@angular/core';

 import { ToasterService } from '../toaster.service';

  import { FormGroup, FormControl, FormBuilder, Validators } from 
 '@angular/forms';
   import { Http, Response, Headers } from '@angular/http';
  import { config } from '../config';
  import { Subject } from 'rxjs';

  import 'rxjs/add/operator/map';
  import { map } from 'rxjs/operators';
  import 'rxjs/Rx';
  import { Observable } from 'rxjs';

  // Statics
  import 'rxjs/add/observable/throw';


 @Component({
  selector: 'app-neo4j-primary',
  templateUrl: './neo4j-primary.component.html',
  styleUrls: ['./neo4j-primary.component.css']
  })

 export class Neo4jPrimaryComponent implements OnInit {

 constructor(private http: Http,  private notify: ToasterService) { }

 ngOnInit() {
this.viewNodesStart();
    }


  emptyObj1;
   emptyObj;
   info;

   // -------------------------------  Nodes Entire Data -------------

  viewNodesStart() {

console.log("INSIDE viewNodesStart()")

// Nodes Value

   console.log("inside Nodes Value");
  var data = localStorage.getItem('token');

 console.log("data is=>",data+ "emptyobj1 = "+ this.emptyObj1);

   var url = config.url;
   var port = config.port;

   var object = {
    "emptyObj" : this.emptyObj
    }
    this.http.post("http://" + url+":" + port + 
    "/viewNodesStart",this.emptyObj1)
  .map(Response => Response)
  .subscribe((res: Response) => {

    console.log("XXXXXXXXXXXX Response on /viewNodesStart", res);

    this.info = res;   

    if (this.info.statusCode == 200) {
      console.log("Data added successfully");

    } else {
      console.log("Data is not inserted")

     }
     });

   }

   }

回答1:

You can send the response back ONLY once, you have an asynchronous operation running while you send the response "It works" and again sending the response with actual data.

res.send sets response headers to object which should ideally happen once during the request lifecycle.

function tmsServer(req, res) { 
    session
     .run('MATCH (n) RETURN n LIMIT 5')
     .then(function (result){
       result.records.forEach(function(record){
         // This will execute only when the promise is resolved and data is returned from database.
         res.send(result); // (RES02)
       });
     })
     .catch(function(err){
      console.log("inside catch = "+err);
     })

     res.send('It Works'); // (RES01) <--- This runs before RES02
    session.close();
}

The solution to your answer is to remove RES01.