Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular universal not reaching api

I'm currently trying to build an angular universal app (whith https://github.com/angular/universal-starter), but I'm facing a problem. When I try to reach my API my application doesn't seem to find it.

This is the basic code I started to wrote:

server.ts

import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { enableProdMode } from '@angular/core';

import * as express from 'express';
import { join } from 'path';
import { readFileSync } from 'fs';

var apiRoute = require("./routes/api");

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist');

// Our index.html we'll use as our template
const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString();

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.bundle');

// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));

/* - Example Express Rest API endpoints -
  app.get('/api/**', (req, res) => { });
*/

app.use("/api/", apiRoute);




// Server static files from /browser
app.get('*.*', express.static(join(DIST_FOLDER, 'browser'), {
  maxAge: '1y'
}));

// ALl regular routes use the Universal engine
app.get('*', (req, res) => {
  res.render('index', { req });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});

api.js

var express = require('express');
var router = express.Router();

router.get("/", function (req, res, next) {
    console.log("ok test");
    res.status(200).json({
        title: "Success",
        obj: "okSuccess"
    });
});

module.exports = router;

app.module.ts

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import {TransferHttpCacheModule} from '@nguniversal/common';
import { HttpClientModule } from '@angular/common/http';
import { HomeService } from './home/home.service';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
  ],
  imports: [
    HttpClientModule,
    BrowserModule.withServerTransition({appId: 'my-app'}),
    RouterModule.forRoot([
      { path: '', component: HomeComponent, pathMatch: 'full'},
      { path: 'lazy', loadChildren: './lazy/lazy.module#LazyModule'},
      { path: 'lazy/nested', loadChildren: './lazy/lazy.module#LazyModule'}
    ]),
    TransferHttpCacheModule,
  ],
  providers: [
    HomeService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

home.component.ts

import { Component, OnInit } from '@angular/core';
import { HomeService } from './home.service';

@Component({
  selector: 'app-home',
  template: `<h3>{{ message }}</h3>`
})
export class HomeComponent implements OnInit {
  public message: string;

  constructor(private homeService: HomeService) { }

  ngOnInit() {
    this.message = 'Hello';
    console.log(this.homeService.apiCall());
   }
}

home.service.ts

import { Injectable } from "@angular/core";
import { Headers, Http, Response } from "@angular/http";
import { HttpClient, HttpHeaders, HttpParams, HttpRequest } from '@angular/common/http';
import 'rxjs/Rx';
import { Observable } from "rxjs/Observable";


@Injectable()
export class HomeService {

    constructor(private httpClient: HttpClient) { }

    apiCall() {
        return this.httpClient.get<any>("/api")
        .map((response) => {
                console.log(response);
                return response;
            })
            .subscribe((response) => {
                console.log(response);
                return response;
            });
    }
}

I start to build in development mode by typing npm run start but I then got the following error

enter image description here I don't really understand why I got this error, it seems like express does not add my route.

like image 672
lanetrotro Avatar asked Oct 15 '25 03:10

lanetrotro


1 Answers

Note: If you look at package.json file, you'll notice that npm run start only calls ng serve, so it's not using angular universal. So the following will not work, as there is no '/api' route/handler defined for the front.

this.httpClient.get<any>("/api")

Instructions for starting angular universal rendering mode are here https://github.com/angular/universal-starter#production-also-for-testing-ssrpre-rendering-locally

Besides, when using angular universal, you cannot use relative URLs when performing ajax calls. You must specify the full url (protocol / domain / port if not 80 or 443 for https)

So for now, you should use

this.httpClient.get<any>("http://localhost:4000/api")

if your angular universal is running on port 4000 on localhost

like image 113
David Avatar answered Oct 17 '25 16:10

David



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!