Using angular material 2 table to display the result from backend based on user's current location

天大地大妈咪最大 提交于 2019-12-12 04:58:23

问题


This is the almost same question as Typescript getCurrent location and pass to backend to get the result and pass to Material Table data source, but this question I only got the answer for how to get the current location and pass to backend and which it works by libertyernie's answer. Therefore I ask this one...

Here is the issue: I want to use Angular Material 2 table to display the list of restaurant (which is come from my spring-boot backend). And based on the tutorial they gave on github, the data source must be observable, which is make sense, because you can sort column or filter the data something like that. But when I try to integrate with current location, I don't know how to make it work...

The scenario is same as the question I linked, which is try to get user's current location, and once it got the location (for example ,lat=123 and lon=123), I will pass this two parameters into my backend address: http://localhost:8080/api/search/location?lat=123&lon=123, and this will return a list of Restaurant, and I need to somehow change to Observable so that the connect() function in ExampleDataSource works.

The code below is what I already tried, but I am failed, the datasource get nothing back.

import { Component, OnInit } from '@angular/core';
import { Http, Response, URLSearchParams } from '@angular/http';
import { DataSource } from '@angular/cdk';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
import { Restaurant } from '../restaurant/restaurant';
import { Category } from '../category/category';
import { RestaurantService } from '../restaurant/restaurant.service';


@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  displayedColumns = ['Id', 'Name', 'Category', 'Address', 'City'];
  exampleDatabase: ExampleHttpDatabase | null;
  dataSource: ExampleDataSource | null;
  location: CurrentLocation | null;
  lat: any;
  lon: any;
  result: Promise<any>;

  constructor(http: Http) {
    this.exampleDatabase = new ExampleHttpDatabase(http);
    this.dataSource = new ExampleDataSource(this.exampleDatabase);
    this.location = new CurrentLocation(http);
  }

  ngOnInit() {
    this.result = this.location.getCurrentLocation(this.lat, this.lon);
    this.result.then(function(result){
      console.log(result._body);
    })
    console.log(this.lat, this.lon);
    this.dataSource.connect();
  }
}

export class ExampleHttpDatabase {
  private restaurantUrl = 'api/restaurant'; // URL to web API
  getRestaurants(): Observable<Restaurant[]> {
    var result = this.http.get(this.restaurantUrl)
      .map(this.extractData);
    result.toPromise();
    return result;
  }

  extractData(result: Response): Restaurant[] {
    return result.json().map(restaurant => {
      return {
        id: restaurant.id,
        name: restaurant.restaurant_name,
        category: restaurant.category.map(c => c.categoryName).join(','),
        address: restaurant.address.address,
        city: restaurant.address.city.city_name
      }
    });
  }
  constructor(private http: Http) { }
}

export class CurrentLocation {
  constructor(private http: Http) { }
  private lat: any;
  private lon: any;
  private params = new URLSearchParams();
  private url = 'api/search/location';


  getPosition = () => {
    var latitude, longitude;
    return new Promise((resolve, reject) => {
      navigator.geolocation.getCurrentPosition((position) => {
        resolve(position.coords);
      }, (err) => {
        reject(err);
      });
    })
  }
  async getCurrentLocation(lat, lon): Promise<any> {
    let coords = await this.getPosition();
    lat = this.lat = coords['latitude'];
    lon = this.lon = coords['longitude'];
    this.params.set('lat', this.lat);
    this.params.set('lon', this.lon);
    var result = this.http.get(this.url, { search: this.params });
    return await result.toPromise();
  }
}

export class ExampleDataSource extends DataSource<Restaurant> {
  constructor(private _exampleDatabase: ExampleHttpDatabase) {
    super();
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<Restaurant[]> {
    return this._exampleDatabase.getRestaurants();
  }

  disconnect() { }
}

Full code also in Github: https://github.com/zhengye1/Eatr/tree/dev


回答1:


Finally I can get the information to display to the home page, but weird behavior happens, please see this link : Weird behavior when using Angular Material 2 table (Angular 2/Spring Boot backend)



来源:https://stackoverflow.com/questions/45618354/using-angular-material-2-table-to-display-the-result-from-backend-based-on-user

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!