Skip to content

Integrate the address field

This document describes how to combine Autocomplete v4, Place v4 and Reverse v4 to build an address field with suggestions:

  1. Autocomplete v4 suggests addresses as the user types.
  2. Place v4 returns the coordinates and address parts of the selected suggestion.
  3. Reverse v4 turns a map pin position into an address.

Requests go through your server to protect the services key.

On the server

// Node.js 18+. Runs on the server; the services key never reaches the browser.
const KEY = process.env.VIETMAP_API_KEY;
const API = "https://maps.vietmap.vn/api";

async function getJson(path, params) {
  const q = new URLSearchParams({ apikey: KEY, ...params });
  const res = await fetch(`${API}/${path}?${q}`);
  if (!res.ok) throw new Error(`${path}: HTTP ${res.status}`);
  return res.json();
}

// Suggestions while typing. focus: the user's "lat,lng", if known
export async function suggest(text, focus) {
  const params = { text, display_type: "5" }; // new format, old one in data_old
  if (focus) params.focus = focus;
  const results = await getJson("autocomplete/v4", params);
  return results.map((r) => ({ refId: r.ref_id, display: r.display }));
}

// The user picked a suggestion: coordinates and address parts for the order
export async function resolve(refId) {
  const p = await getJson("place/v4", { refid: refId });
  return {
    display: p.display, lat: p.lat, lng: p.lng,
    houseNumber: p.hs_num, street: p.street,
    wardId: p.ward_id, ward: p.ward, cityId: p.city_id, city: p.city,
  };
}

// The user dragged the pin: coordinates -> nearest address
export async function pinToAddress(lat, lng) {
  const [nearest] = await getJson("reverse/v4", { lat, lng, display_type: "1" });
  return nearest ? { display: nearest.display, lat: nearest.lat, lng: nearest.lng } : null;
}
import os

import requests

KEY = os.environ["VIETMAP_API_KEY"]
API = "https://maps.vietmap.vn/api"


def get_json(path, params):
    resp = requests.get(f"{API}/{path}", params={"apikey": KEY, **params}, timeout=10)
    resp.raise_for_status()
    return resp.json()


def suggest(text, focus=None):
    """Suggestions while typing. focus: the user's "lat,lng", if known."""
    # display_type=5: new format, old one in data_old
    results = get_json("autocomplete/v4", {"text": text, "focus": focus, "display_type": 5})
    return [{"ref_id": r["ref_id"], "display": r["display"]} for r in results]


def resolve(ref_id):
    """The user picked a suggestion: coordinates and address parts for the order."""
    p = get_json("place/v4", {"refid": ref_id})
    keys = ("display", "lat", "lng", "hs_num", "street", "ward_id", "ward", "city_id", "city")
    return {k: p[k] for k in keys}


def pin_to_address(lat, lng):
    """The user dragged the pin: coordinates -> nearest address."""
    results = get_json("reverse/v4", {"lat": lat, "lng": lng, "display_type": 1})
    return results[0] if results else None
Build a delivery address field with suggestions for my checkout page, using the VIETMAP APIs.

My server has three endpoints that call VIETMAP with the services key:
1. Suggest: GET https://maps.vietmap.vn/api/autocomplete/v4 (text, focus, display_type=5) -> list of {ref_id, display}
2. Pick: GET https://maps.vietmap.vn/api/place/v4 (refid) -> display, lat, lng, hs_num, street, ward_id, ward, city_id, city
3. Drag pin: GET https://maps.vietmap.vn/api/reverse/v4 (lat, lng, display_type=1) -> nearest address

In the browser: call the suggest endpoint only with at least 2 characters and after the user stops typing for 300 ms.

Requirements:
- Read the API key from the VIETMAP_API_KEY environment variable on the server; never send it to the browser.
- Check the HTTP status (401: wrong key, 423: quota used up or API not enabled).
- Read the docs below first. Use only parameters and response fields documented there.

Docs:
- https://maps.vietmap.vn/docs/map-api/use-cases/checkout-address-guide/index.txt
- https://maps.vietmap.vn/docs/map-api/autocomplete-version/autocomplete-v4/index.txt
- https://maps.vietmap.vn/docs/map-api/place-v4/index.txt
- https://maps.vietmap.vn/docs/assets/agents/search-geocoding.txt

In the browser: send requests when the user stops typing

The code below sends a request after the user stops typing for 300 ms, which saves transactions:

// Browser: call your own server's endpoint, not VIETMAP directly
const input = document.querySelector("#address");
let timer;
input.addEventListener("input", () => {
  clearTimeout(timer);
  const text = input.value.trim();
  if (text.length < 2) return; // Autocomplete needs at least 2 characters
  timer = setTimeout(async () => {
    const res = await fetch(`/address/suggest?text=${encodeURIComponent(text)}`);
    showSuggestions(await res.json()); // your function that renders the list
  }, 300); // call once the user has stopped typing for 300 ms
});

To show a map with a pin, use VietMap GL JS as in Quickstart, step 4 with a draggable marker. When the pin is dropped, send its coordinates to your Reverse endpoint.

Old and new addresses

Autocomplete v4 accepts addresses in the old and the new administrative units. The code above uses display_type=5: the new address, with the old version in data_old. The other values are on Autocomplete v4.

For new orders, store the address in the new format with ward_id, city_id and the coordinates. Stored old addresses can be converted with the Address Migration API.

  • Geocode v4 — coordinates for a whole address string in one call, for example an address pasted from elsewhere.
  • Logistics and delivery — dispatch and route optimization for a fleet.
  • Error codes — handling 401, 423 and 429.
Hotline
Tổng đài hỗ trợ
089.616.4567
Messenger Chat Facebook zalo Chat Zalo