如何使用附近搜索功能通过Google Places API获得评论?

时间:2019-06-27 17:01:03

标签: javascript google-maps vue.js google-places-api vue-cli

关于我的餐厅应用项目的最后一个问题。

我实现了Google地方信息,并在我的Vue应用商店中获得了餐厅,这些餐厅也显示在地图上。

我读到有关通过Google地方信息获得评论的信息,但没有实现。

这就是我开始的内容。 如果有人可以告诉我我做对的方法。

restaurantFactory.js的代码,这是商店中使用的js文件,它管理获取餐馆的所有逻辑,其中一些来自Json文件,其他来自Google Places:

export default {
  getRestaurantList
};

const axios = require('axios');

// Appel Axios à la liste restaurantList.json, et de GooglePlaces, réutilisée dans le Store.
async function getRestaurantList(service, location) {
  try {
    const jsonPromise = axios.get('http://localhost:8080/restaurantList.json')
    const placesPromise = getPlacesPromise(service, location)

    const [ jsonResult, placesResult ] = await Promise.all([ jsonPromise, placesPromise ])

    const jsonRestaurantList = jsonResult.data
    const placesRestaurantList = placesResult.result.map(formatPlacesIntoJson)

    return [
      ...jsonRestaurantList,
      ...placesRestaurantList
    ]
  } catch (err) {
    console.log(err)
    return false
  }
}

/* Deux fonctions helpers de getRestaurantList utilisée dans le Store */

// Pour obtenir les places en utilisant l'API
function getPlacesPromise (service, location) {
  return new Promise((resolve) => {
    return service.nearbySearch({
      location,
      radius: 2000,
      type: ['restaurant']
    }, function (result, status) {
      // Appel de getPlacesDetails
      return resolve({ result, status })
    });
  })
}

// function getPlacesDetails (service) {
//   return new Promise((resolve) => {
//     const request = {
//     // forEach de type restaurant par place_id
//     // fields ['reviews']
//     }
//     return service.getDetails()
//   })
// }

// Pour formater les données de GooglePlaces de la même manière que les restaurants de la liste JSON
function formatPlacesIntoJson (restaurant) {
  // console.log(restaurant);
  return {
    ...restaurant,
    restaurantName: restaurant.name,
    address: restaurant.vicinity,
    lat: restaurant.geometry.location.lat(),
    long: restaurant.geometry.location.lng(),
    description: '',
    // ratings: [{
    //   stars: reviews.rating,
    //   author: reviews.author_name,
    //   comment: reviews.text
    // }]
  }
}

Store.js:

import Vue from 'vue';
import Vuex from 'vuex';

import restaurantFactory from '../interfaces/restaurantFactory';

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    restaurantList: [],
    visibleRestaurant: [],
    sortValue: [],
    boundsValue: {}
  },
  getters: {
    // Obtenir l'ID des restaurants
    getRestaurantById: (state) => {
      return (id) => {
        const restaurantIndex = getRestaurantIndex(state.restaurantList, id);
        // console.log({
        //   id,
        //   restaurantIndex
        // });
        return state.restaurantList[restaurantIndex];
      };
    },
    getRestaurantList: state => {
      return state.visibleRestaurant;
    },
    getSortValue: (state) => {
      return state.sortValue;
    },
    getBoundsValue: (state) => {
      return state.boundsValue;
    },
  },
  mutations: {
    setRestaurantList: (state, {
      list
    }) => {
      state.restaurantList = list;
    },
    // Définit les restaurants à afficher en fonction des limites de la carte et du tri par moyenne
    selectVisibleRestaurant(state) {
      const bounds = state.boundsValue;
      const range = state.sortValue;
      state.visibleRestaurant = state.restaurantList.filter((restaurant) => {
        let shouldBeVisible = true;
        let isInMap = true;
        let isInRange = true;
        // Limites cartes
        if (bounds) {
          isInMap = restaurant.long >= bounds.ga.j && restaurant.long <= bounds.ga.l && restaurant.lat >= bounds.na.j && restaurant.lat <= bounds.na.l;
          shouldBeVisible = shouldBeVisible && isInMap;
        }
        // Moyenne des notes
        if (range && range.length === 2) {
          isInRange = restaurant.avgRating >= range[0] && restaurant.avgRating <= range[1];
          shouldBeVisible = shouldBeVisible && isInRange;
        }

        return shouldBeVisible;
      });
    },
    setBoundsValue: (state, bounds) => {
      state.boundsValue = bounds;
    },
    setSortValue: (state, range) => {
      state.sortValue = range;
    },
    // Ajoute un restaurant en ajoutant automatiquement un champ avgRating et un ID (le dernier +1)
    addRestaurant: (state, { newRestaurant }) => {

      const ratings = newRestaurant.ratings || []

      const restaurantToAdd = {
        ...newRestaurant,
        ratings,
        avgRating: computeAvgRatings(ratings),
        ID: getLastId()
      }

      state.restaurantList.push(restaurantToAdd)
      state.visibleRestaurant.push(restaurantToAdd)

      function getLastId() {
        const lastId = state.restaurantList.reduce((acc, restaurant) => {
          if (acc < restaurant.ID) {
            return restaurant.ID
          }
          return acc
        }, 0)

        return lastId + 1
      }
    },
    // Ajoute un commentaire
    addComment: (state, {
      restaurantId,
      comment
    }) => {
      const restaurantIndex = getRestaurantIndex(state.restaurantList, restaurantId);

      state.restaurantList[restaurantIndex].ratings.push({
        ...comment
      })

      const restaurantRating = computeAvgRatings(state.restaurantList[restaurantIndex].ratings);
      state.restaurantList[restaurantIndex].avgRating = restaurantRating;
    }
  },
  // Fait appel à restaurantFactory et ajoute les restaurants de la liste JSON et de GooglePlaces
  actions: {
    getData: async function (context, { service, location }) {
      const restaurantList = await restaurantFactory.getRestaurantList(service, location)

      restaurantList.forEach((newRestaurant) => context.commit('addRestaurant', { newRestaurant }))
    },
  }
});

// Fonction helper pour getRestaurantById
function getRestaurantIndex(restaurantList, id) {
  return restaurantList
    .findIndex((restaurant) => restaurant.ID === parseInt(id))
}
// Fonction helper pour getRestaurantAvgRating
function computeAvgRatings (ratings) {
  const avgRating = ratings.reduce((acc, rating) => {
    return acc + (rating.stars / ratings.length);
  }, 0);
  return Math.round(avgRating);
}

然后对于地图,我使用这样的Google Places(mainMap组件):

// Google Places
      setPlaces(location) {
        const service = new this.google.maps.places.PlacesService(this.map);
        // Appel l'action getData du Store
        this.$store.dispatch('getData', {
          service,
          location
        })
      }

我开始使用的新功能在restaurantFactory.js中有注释

我想到了使用getDetails来获取评论数组的方法,即使用每个餐厅的place_id。 我只是现在不知道如何实现它。 谢谢。

0 个答案:

没有答案