problem description
 I"m using Angular to build a client, hoping to get the latest real-time prices from the server by clicking on the following items on the page. But when I click the client button, I report the exception of core.js:1633 ERROR SyntaxError: Unexpected token in JSON at position 0. Browser debugging errors are as follows: 
 

 
 
has been bothering me for two days. I can find a way to try on the Internet, but I can"t solve it. It is said that it is possible to use JSON to convert client and server data in the wrong format of JSON.stringify and JSON.parse. But I still can"t find it. Ask the bosses for help.
related codes
client
product-detail.component.html
<div class="thumbnail">
  <img src="http://temp.im/820x300">
  <div>
    <h4 class="pull-right">{{product?.price}}</h4>
    <h4>{{product?.price}}</h4>
    {{product?.desc}}
  </div>
  <div>
    <p class="pull-right">{{comments?.length}}
    
      <app-stars [rating]="product?.rating"></app-stars>
    
  </div>
</div>
<div class="thumbnail">
  <button class="btn btn-default btn-lg" [class.active]="isWatched" (click)="watchProduct()">
    {{isWatched?"":""}}
  </button>
  <label>:{{currentBid | number:".2-2"}}</label>
</div>
<div class="well">
  <div>
    <button class="btn btn-success" (click)="isCommentHidden = !isCommentHidden"></button>
  </div>
  <div [hidden]="isCommentHidden">
    <div><app-stars [(rating)]="newRating" [readonly]="false"></app-stars></div>
    <div><textarea [(ngModel)]="newComment"></textarea></div>
    <div><button class="btn" (click)="addComment()"></button></div>
  </div>
  <div class="row" *ngFor="let comment of comments">
    <hr>
    <div class="col-md-12">
      <app-stars [rating]="comment.rating"></app-stars>
      <span>{{comment.user}}</span>
      <span class="pull-right">{{comment.timestamp}}</span>
      
      {{comment.content}}
    </div>
  </div>
</div>product-detail.component.ts
import { Component, OnInit } from "@angular/core";
import {ActivatedRoute} from "@angular/router";
import {Comment, Product, ProductService} from "../shared/product.service";
import {WeSocketService} from "../shared/we-socket.service";
@Component({
  selector: "app-product-detail",
  templateUrl: "./product-detail.component.html",
  styleUrls: ["./product-detail.component.css"]
})
export class ProductDetailComponent implements OnInit {
  product: Product;
  comments: Comment [];
  isWatched: boolean = false;
  currentBid: number;
  newRating: number = 5;
  newComment: string = "";
  isCommentHidden: boolean = true;
  constructor(private routInfo: ActivatedRoute,
              private productService: ProductService,
              private webService: WeSocketService
  ) { }
  ngOnInit() {
    let productId: number = this.routInfo.snapshot.params["productId"];
    this.productService.getProduct(productId).subscribe(
      product => {
        this.product = product;
        this.currentBid = this.product.price;
      }
      );
    this.productService.getProductForProductId(productId).subscribe(
      comment => this.comments = comment
    );
  }
  addComment() {
    let comment = new Comment(0, this.product.id, new Date().toISOString(), "SomeOne", this.newRating, this.newComment);
    this.comments.unshift(comment);
    let sum = this.comments.reduce((sum, comment) => sum + comment.rating, 0);
    this.product.rating = sum / this.comments.length;
    this.newComment = null;
    this.newRating = 5;
    this.isCommentHidden = true;
  }
  watchProduct() {
    this.isWatched = !this.isWatched;
    this.webService.creatObservableSocket("ws://localhost:8085", this.product.id)
      .subscribe(
        products => {
          let produc = products.find(p => p.productId === this.product.id);
          this.currentBid = produc.bid;
        }
      );
  }
}we-socket.service.ts
import { Injectable } from "@angular/core";
import {observable, Observable} from "rxjs";
import "rxjs/Rx";
@Injectable({
  providedIn: "root"
})
export class WeSocketService {
  ws: WebSocket;
  constructor() { }
  creatObservableSocket(url: string, id: number): Observable<any> {
    this.ws = new WebSocket(url);
    return new Observable<string>(
      observable => {
        this.ws.onmessage = (event) => observable.next(event.data);
        this.ws.onerror = (event) => observable.error(event);
        this.ws.onclose = (event) => observable.complete();
        this.ws.onopen = (event) => this.sendMessage({productId: id});
      }
    ).map(message => {JSON.parse(message)});
  }
  sendMessage(message: any) {
    this.ws.send(JSON.stringify(message));
  }
}
  Server  
 auction_service.ts 
import * as express from "express";
import {Server} from "ws";
const app = express();
export class Product {
    constructor(
        public id: number,
        public title: string,
        public price: number,
        public rating: number,
        public desc: string,
        public categories: Array<string>
    ) {
    }
}
export class Comment {
    constructor(
        public id: number,
        public productId: number,
        public timestamp: string,
        public user: string,
        public rating: number,
        public content: string
    ) {
    }
}
const products: Product[] = [
    new Product(1, "", 1.99, 1.5, "Angular", ["", ""]),
    new Product(2, "", 2.99, 3.5, "Angular", [ ""]),
    new Product(3, "", 3.99, 4.5, "Angular", ["", ""]),
    new Product(4, "", 4.99, 2.5, "Angular", [""]),
    new Product(5, "", 5.99, 1.5, "Angular", ["", ""]),
    new Product(6, "", 6.99, 3.5, "Angular", [""]),
];
const comments: Comment[] = [
    new Comment(1, 1, "2018-02-22 1:15:13", "", 3, "~"),
    new Comment(2, 1, "2018-03-02 21:15:13", "", 2, "~"),
    new Comment(3, 1, "2018-06-22 15:12:03", "", 4, "~"),
    new Comment(4, 2, "2018-04-22 17:20:13", "", 1, ""),
    new Comment(5, 2, "2018-07-22 11:15:13", "", 4, ""),
]
app.get("/", (req, res) =>{
    res.send("Hello Express")
});
app.get("/api/products", (req, res) =>{
    let result = products;
    let params = req.query;
    if (params.title){
        result = result.filter((p) => p.title.indexOf(params.title) !== -1);
    }
    if (params.price && result.length > 0){
        result = result.filter((p) => p.price <= parseInt(params.price));
    }
    if (params.category && result.length >0){
        result = result.filter((p) => p.categories.indexOf(params.category) !== -1)
    }
    res.json(result);
});
app.get("/api/product/:id", (req, res) =>{
    res.json(products.find((product) => product.id == req.params.id))
});
app.get("/api/product/:id/comments", (req, res) =>{
    res.json(comments.filter((comment: Comment) => comment.productId == req.params.id))
});
const server = app.listen(8000,"localhost", () =>{
    console.log(":http://localhost:8000");
});
const subscriptions = new Map<any, number[]>();
const wsServer = new Server({port: 8085});
wsServer.on("connection", websocket =>{
    websocket.send("");
    websocket.on("message", message =>{
        let messageObj = JSON.parse(message);
        let productIds = subscriptions.get(websocket) || [];
        subscriptions.set(websocket, [...productIds, messageObj.productId]);
    });
});
const currentBids = new Map<number, number>();
setInterval(() =>{
    products.forEach(p =>{
        let currentBid = currentBids.get(p.id) || p.price;
        let newBid = currentBid + Math.random()*5;
        currentBids.set(p.id, newBid);
    })
    subscriptions.forEach((productIds: number[], ws) => {
        if (ws.readyState === 1){
            let newBids = productIds.map(pid => ({
                productId: pid,
                bid: currentBids.get(pid)
            }));
            ws.send(JSON.stringify(newBids));
        }else {
            subscriptions.delete(ws);
        }
    });
},2000);