I have this app with Express backend:
server.js
:
var express = require('express');
var methodOverride = require('method-override')
var app = express();
var bodyParser = require('body-parser');
var cors = require('cors');
var mysql = require('mysql');
...
app.use(methodOverride('X-HTTP-Method-Override'))
app.use(bodyParser.json());
app.use(cors());
...
app.route('/api/lessons').get((req, res) => {
con.query('SELECT * FROM lesson', (err, rows) => {
if (err)
res.send(JSON.stringify({ "status": 500, "error": err, "response": null }));
else
res.send(JSON.stringify({ "status": 200, "error": null, "response": rows }));
});
});
...
app.route('/api/lessons/:lessonId').put(function (req, res) {
console.log("Backend PUT");
var lessonId = req.param('lessonId');
con.query('UPDATE lesson SET title=?, body=?, level_id=? WHERE id=?', [req.body.title, req.body.body, req.body.level_id, lessonId], (err, rows) => {
if (err)
res.send(JSON.stringify({ "status": 500, "error": err, "response": null }));
else
res.send(JSON.stringify({ "status": 200, "error": null, "response": rows }));
});
});
...
app.route('/api/lessons/:lessonId').delete((req, res) => {
console.log("Backend DELETE");
var lessonId = req.param('lessonId');
con.query('DELETE FROM lesson WHERE id=?', [lessonId], (err, rows) => {
if (err)
res.send(JSON.stringify({ "status": 500, "error": err, "response": null }));
else
res.send(JSON.stringify({ "status": 200, "error": null, "response": rows }));
});
});
Angular service:
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Configuration } from '../../app.constants';
@Injectable()
export class LessonService {
private restUrl: string;
constructor(private http: HttpClient) {
this.restUrl = 'http://localhost:8000/api/lessons/';
}
public getAll() {
return this.http.get(this.restUrl);
}
public getOne(id: number) {
return this.http.get(this.restUrl + id);
}
public getAllForLevel(id: number) {
return this.http.get('http://localhost:8000/api/lessons-for-level/' + id);
}
...
public update(id: number, level: any) {
console.log(this.restUrl+id);
return this.http.put(this.restUrl + id, level);
}
public delete(id: number) {
console.log("DELETE: " + this.restUrl + id);
return this.http.delete(this.restUrl + id);
}
...
}
All the GET methods are working correctly, but not the PUT or the DELETE method. With console.log
's I concluded that the service methods update
and delete
are getting called from the frontend, but the REST endpoints (in server.js
) are never called. There are no error messages at all.
What could be the problem?
Edits: Besides the PUT method, the DELETE is also not getting called. I've edited the title and the question. Also I've added console.log
s in the update
and delete
methods so I can check what URL is being called, and it is http://localhost:8000/api/lessons/2
(for example), so it's correct. I've tried calling that URL via Postman both for PUT and DELETE and it works correctly, it changed or deleted the relevant entry in the DB. So as it looks to me, the only problem is the lack of communication between frontend and backend.
I've found the solution.
tl;dr:
I didn't put the .subscribe
in the place where I call the update
method.
Long version:
When I call various get
methods from my service, I do it like this:
this.lessonService.getAllForLevel(this.levelId).subscribe(data => this.lessons = data['response']);
However, I thought that I can call my update
method like this:
this.lessonService.update(this.lessonId, this.lesson);
...because I thought there was nothing interesting that I should subscribe to.
However, when I changed the call to this:
this.lessonService.update(this.lessonId, this.lesson).subscribe(data => console.dir(data));
...it worked correctly (don't mind the console.dir
part, I just wanted to put something in the subscribe
part so it would work).