2

I am using angular 5 with node js to make a crud for events data. When I am trying to get events data from 4200 port(http://localhost:4200/event) which is running through angular is working well. It is showing the data in html with all the values. But when I am using 8080 port(http://localhost:8080/event) which one is from nodejs it is showing data only in json. No html content from event.component.html is showing here. express.js looks like this

/* ===================
Import Node Modules
=================== */
const express = require('express');
const app = express();
const router = express.Router();

const mongoose = require('mongoose');
const config = require('./database');
const path = require('path');
const appRoot = require('app-root-path');

//custom module
const event = require('../config/routes/event.router');

const bodyParser = require('body-parser');
const cors = require('cors');
const port = process.env.PORT || 8080; // Allows heroku to set port


mongoose.Promise = global.Promise;
//assigning value 
process.env.NODE_ENV = 'devlopment';

/**
 * Database connection
 */

mongoose.connect(config.uri, {
  useMongoClient: true,
}, (err) => {
  // Check if database was able to connect
  if (err) {
    console.log('Could NOT connect to database: ', err); // Return error message
  } else {
    console.log('Connected to ' + config.db); // Return success message
  }
});

app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());


app.use(express.static(path.join(appRoot.path, 'dist')));

/**
 * Routing
 */

app.use('/event', event); //Event Router

app.get('*', (req, res) => {
 res.sendFile(path.join(appRoot.path, 'dist/index.html'));
});

/**
 * Assiging port to server
 */
app.listen(port, () => {
  console.log('Listening on port ' + port + ' in ' + process.env.NODE_ENV + ' mode');
});

my event.router.js looks like this

const Event = require('../../model/event.model');
var multer  = require('multer');
var upload  = multer({ dest: './public/uploads/img/',fileFilter:function(req,file,cb){
  var ext = file.originalname.split('.').pop();
  cb(null, file.fieldname + '-' + Date.now() + '.' + ext);
    }
}).single('eventimage');

/* GET ALL EVENTS */
router.get('/', function(req, res, next) {
  Event.find(function (err, events) {
    if (err) return next(err);
    res.json(events);
  });
});

/* GET SINGLE EVENT BY ID */
 router.get('/:id', function(req, res, next) {
   Event.findById(req.params.id, function (err, post) {
     if (err) return next(err);
     res.json(post);
   });
 });

module.exports = router;

event.component.html looks like this

<div class="container">
  <h1>Event List</h1>
  <table class="table">
    <thead>
      <tr>
        <th>Event Id</th>
        <th>Event Name</th>
        <th>Event Desc</th>
        <th>Event Date</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let event of events">
        <td><a routerLink="/event-details/{{ event._id }}">{{ event._id }}</a></td>
        <td>{{ event.eventname }}</td>
        <td>{{ event.eventdesc }}</td>
        <td>{{ event.eventdates }}</td>
      </tr>
    </tbody>
  </table>
</div>

event.components.ts looks like this

import { Component, OnInit } from '@angular/core';
import { EventService } from '../event.service';

@Component({
  selector: 'app-event',
  templateUrl: './event.component.html',
  styleUrls: ['./event.component.css']
})
export class EventComponent implements OnInit {

  events: Event[] = [];

  constructor(
    protected eventService: EventService
    ) { }

  ngOnInit() {
    this.getAll();
  }

  getAll() {
    this.eventService.getEvents().subscribe(res => {
      this.events = res as Event[];
    }, err => {
      console.log(err);
    });
  }
}

event.service.ts looks like this

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs';
import { HttpClientModule } from '@angular/common/http';

import { HttpClient } from "@angular/common/http";
import 'rxjs/add/operator/map';


@Injectable()
export class EventService {

  domain = 'http://localhost:8080';

  headers = new Headers({ 'Content-Type': 'application/json' });

  constructor(
   private http: Http,
    ) { }

  getEvent(id: string) {
    return this.http.get(this.domain + '/event/' + id, { headers: this.headers }).map(res => res.json());
  }

  getEvents(){
    return this.http.get( this.domain + '/event', {headers: this.headers}).map(res => res.json() );
  }

}

So can someone tell me what is the wrong here. Why I am getting data as json in 8080 port and why its showing fine with 4200 port? How I will get the data with html in 8080 port? Any help and suggestions will be really appreciable.

4
  • it seems like the problem is that you have the same /event route in two different routers. when the pages are separated, the appropriate one is activated for the app running on that port. however, when the apps are combined into one port, the express route /event will always happen, and the angular /event route cannot happen at all. Commented Feb 6, 2018 at 8:03
  • so how can I fix that? Commented Feb 6, 2018 at 8:08
  • use two different routes..... typically the server would use something like /api/event to avoid the conflict. Commented Feb 6, 2018 at 8:10
  • can you share some code for this? So that I can have an idea about that? Commented Feb 6, 2018 at 8:15

3 Answers 3

1

I knew this collision would occur when I told you to move events above get * request in other answer.

That is why suggested the /api route.

The thing happening here is :-

When you are serving your angular app from node. i.e on port 8080 and request

http://localhost:8080/events

the express finds this route registered in events module, so it returns the data, which is in form of JSON and the request does not go to the route where you return the index file (needed to load angular)

While localhost:4200 request are directly sent to angular CLI so they don't collide with express path.

As I suggested, Just put the "/api" path ahead of every api that you make in express and your issue would be resolved as express will no longer have an "/events" path so it will pass the request to app.get(*) function and your angular file would be served.

NOTE /api is just a standard naming convention, You can put xyz and it would work as well.

This practice will also ensure that You don't face the same problem in other requests.

Sign up to request clarification or add additional context in comments.

1 Comment

Hello, Can you answer my another question? stackoverflow.com/questions/48803725/…
1

your event route is providing the json for the event call in the angular app, not rendering it.

Your angular app is also running on a webserver on 4200, which is probably some kind of development server. The requests are then being proxied to the express server which provides the backend data.

To use the express application to also render the angular app you need to build the application and place the files into the dist folder of the express app. Then, any route other than /event will render the angular app. This is the section of code which shows that.

app.get('*', (req, res) => {
 res.sendFile(path.join(appRoot.path, 'dist/index.html'));
});

If you are in a development environment then there is no need to worry about this. You can access the angular app on port 4200 and the express app on 8080

Comments

0

It's very logic to see the HTML with data in port 4200 as in this port you host your HTML files of Angular so you will see the HTML whatever your backend works or not.

On Port 8080 It's very logical too as this the port hosting the backend it sends data only and this port is the port providing HTML on port 4200 with data.

1 Comment

Is there any way to get html files in that 8080 port with data?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.