You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Maps标记点击报错:Missing parameter. You must specify placeId

问题排查与解决:Google Maps Marker点击触发placeId缺失错误

问题概述

原本正常运行的Google Maps相关代码,调整后出现「Unhandled Promise Rejection: Error: Missing parameter. You must specify placeId」错误,恢复原代码后问题依旧。点击Marker弹出InfoWindow时触发报错,排查确认marker.placeId的值为undefined。

成因分析

  1. placeId存取方式不匹配:代码中通过MarkerPlaceID.set(marker, place.placeId)将placeId存入自定义Map,但在handleMarkerClick中直接尝试读取marker.placeId——Google Maps的Marker对象本身没有内置placeId属性,这种读取方式无法获取到之前存储的值。
  2. 浏览器缓存残留:恢复原代码后,浏览器可能仍加载了旧的缓存文件,导致修改未生效。
  3. 潜在数据缺失(次要):虽然之前正常运行,但textSearch返回的部分place对象可能存在placeId为空的情况,不过这并非当前报错的直接原因。

解决办法

方案1:统一placeId的存取方式

方式A:直接给Marker挂载自定义属性(更简洁)

修改搜索算法中的代码,将MarkerPlaceID.set(marker, place.placeId)替换为直接给marker添加属性:

// 替换原有的 MarkerPlaceID.set(marker, place.placeId);
marker.placeId = place.placeId;

这样handleMarkerClick中marker.placeId的读取逻辑就能正常工作。

方式B:使用Map的get方法读取

如果坚持使用MarkerPlaceID这个Map存储,修改handleMarkerClick中的placeId获取逻辑:

// 替换原有的 const request = { placeId: marker.placeId, ... };
const placeId = MarkerPlaceID.get(marker);
const request = {
  placeId: placeId,
  fields: [
    "name",
    "formatted_address",
    "photos",
    "formatted_phone_number",
    "website",
    "opening_hours",
    "rating",
    "reviews",
  ],
};

方案2:清除浏览器缓存

  • 按Ctrl+Shift+R(Windows/Linux)或Cmd+Shift+R(Mac)强制刷新页面,加载最新代码;
  • 或在浏览器开发者工具的「网络」面板中勾选「禁用缓存」,重新加载页面。

方案3:添加数据校验(可选)

为避免因place对象无placeId导致的后续报错,在创建Marker前添加校验:

results.forEach((place) => {
  if (!place.name.includes("ديوان") && place.placeId) { // 新增placeId校验
    // 创建Marker及后续逻辑
  }
});

修改后的关键代码示例

搜索算法(使用自定义属性方式)

const service = new google.maps.places.PlacesService(map);
service.textSearch(request, (results, status) => {
  if (status === google.maps.places.PlacesServiceStatus.OK) {
    results.forEach((place) => {
      if (!place.name.includes("ديوان") && place.placeId) {
        const marker = new google.maps.Marker({
          map,
          position: place.geometry.location,
        });

        const infoWindow = new google.maps.InfoWindow();
        // 直接挂载placeId到marker对象
        marker.placeId = place.placeId;
        marker.addListener("click", () => {  
          handleMarkerClick(marker);
          resultRowCLick(marker);
        });
      
        google.maps.event.addListener(map, 'click', function() {
          infoWindows.forEach(function(infoWindow) {
            infoWindow.close();
          });
        });
        markers.push(marker);
        
        addNewResultRow(place.name, place.formatted_address, marker);
      } 
    });

    console.log("Nearby search results:", results);
  } else {
    console.error("Error performing nearby search:", status);
  }
});

handleMarkerClick函数(无需修改,若使用方案A)

function handleMarkerClick(marker) {
  infoWindows.forEach((infoWindow) => {
    infoWindow.close();
  });
  
  let infoWindow = new google.maps.InfoWindow();
  
  window.addEventListener('keydown', (event) => {
    if (event.keyCode === 27) {
      infoWindow.close();
    }
  });

  const request = {
    placeId: marker.placeId,
    fields: [
      "name",
      "formatted_address",
      "photos",
      "formatted_phone_number",
      "website",
      "opening_hours",
      "rating",
      "reviews",
    ],
  };

  const service = new google.maps.places.PlacesService(map);
  service.getDetails(request, (place, status) => {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
      let content = '<div style="max-width: 250px;">';

      if (place.photos && place.photos.length > 0) {
        const photoUrl = place.photos[0].getUrl();
        content += '<div class="image-container">';
        content += `<img src="${photoUrl}" alt="${place.name}" style="max-width: 250px; max-height: 150px;">`;
        content += '</div>';
      }
      
      content += `<h2>${place.name}</h2>`;
      content += `<p>Address: ${place.formatted_address}</p>`;

      if (place.website) {
        content += `<p>Website: <a href="${place.website}" target="_blank">${place.website}</a></p>`;
      }
      if (place.formatted_phone_number) {
        content += `<p>Phone: ${place.formatted_phone_number}</p>`;
      }
      if (place.opening_hours) {
        content += `<div class="times">`
        content += `<br><p>Opening Hours:</p>`;
        content += `<p>${place.opening_hours.weekday_text.map(line => `&nbsp;&nbsp;&nbsp;&nbsp;${line}`).join("<br>")}</p>`;
        content += `</div>`
      }
      if (place.rating) {
        content += '<div class="rating-container">';

        content += '<p>';
        content += `rating: &nbsp;${place.rating}`;
        for (let i = 0; i < place.rating; i++) {
          content += '&nbsp<i class="fa fa-star"></i>';
        }
        
        content+= "</p>"

        content += '</div>';
      }
      if (place.reviews && place.reviews.length > 0) {
        content += '<p>Reviews:</p>';
        content += '<ul>';
        
        place.reviews.forEach((review) => {
          if (review.text && review.text.trim().length > 0) {
            content += `<li class="review-item">${review.text}</li>`;
          }
        });
        
        content += '</ul>';
      }

      content += '</div>';
      infoWindow.setContent(content);
      infoWindow.open(map, marker);

      infoWindows.push(infoWindow);
    } else {
      console.error("Error fetching Place Details:", status);
    }
  });
}

内容的提问来源于stack exchange,提问作者Nayef Alhajraf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:25:56