Search code examples
angularrestjson-server

Angular 5+ http post issue


I'm able to retrieve my objects just fine from a JSON file that resides on my localhost. However, upon post, I get.

Cannot read property 'id' of undefined

On the mock object I'm passing in, If I add an id property and some random number, it works. But I don't want to have to pass in an id.

Here's the service:

@Injectable()
export class TileService {

  tiles$ = new Subject<any>();
  details$  = new Subject<any>();
  messages$  = new Subject<any>();

  private tilesUrl = 'http://localhost:3000/tiles';

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

  constructor(private http: HttpClient) { }

  getTiles(): Observable<Tile[]> {
    return this.http.get<Tile[]>(this.tilesUrl);
  }

   createTile(t: Tile) {
    return this.http.post<Tile>(this.tilesUrl, t, this.httpOptions).subscribe(
      res => {
        console.log(res);
      },
      (err: HttpErrorResponse) => {
        console.log(err.error);
        console.log(err.name);
        console.log(err.message);
        console.log(err.status);
      }
    );
   }

}

Here is where I pass in the mock object:

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

export class AvailableTilesComponent implements OnInit {

  title = 'Available Tiles';

  tiles: Tile[];


  mockNewTile = {
    title: 'GO',
    description: 'Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.',
    code: {
        snippetA: 'something here.',
        }
  };

  constructor(private tileService: TileService) { }

  ngOnInit() {
    this.tileService.getTiles().subscribe(x => this.tiles = x);
  }

  addTile(t: Tile) {
    this.tileService.tileStream(t);
    this.tileService.messageStream( t.title +  ' tile added.');
  }

  createTile() {
    this.tileService.createTile(this.mockNewTile);
  }
}

I'm using json-server to allow REST operations on my localhost.

Contents of http://localhost:3000/tiles.json

{
  "tiles": [
    {
      "title": Language A",
      "description": "Language A description.",
      "code": {
        "snippetA": "lang snippet a1",
        "snippetB": "lang snippet a2",
        "snippetC": "lang snippet a3"
      }
    },
       {
      "title": Language B",
      "description": "Language B description.",
      "code": {
        "snippetA": "lang snippet b1",
        "snippetB": "lang snippet b2",
        "snippetC": "lang snippet b3"
      }
    }
  ]
}

Solution

  • There are two ways you can solve this issue.

    1. If you have access to the back-end code you can change it to ignore the id field form the request accepted. Instead to auto increment the id field.

    2. You can pass an id without the user entering an id.


    npm install uuid --save
    

    import { v4 as uuid } from 'uuid';
    
     mockNewTile = {
          id : uuid(),
          title: 'GO',
          description: 'Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.',
          code: {
              snippetA: 'something here.',
           }
       };
    

    I hope that helps. If it does not work plz feel free to comment. I am right there.