admin管理员组

文章数量:1384214

I am developing a node.js API with using express and mongodb, I am using google places api with autocomplete but getting status code 400 error.

Why google place api not giving me google suggestions as per my needs, check my postman, I also send bearer token in headers and inside body - raw I pasted this query in json: {"input": "Athreya Hospital"}

App.js file, check Map route:

const dotenv = require("dotenv");
dotenv.config();
const express = require("express");
const cors = require('cors');
const cookirParser = require('cookie-parser');
const connectToDb = require('./db/db');
const userRoutes = require('./routes/user.routes');
const captainRoutes = require('./routes/captain.routes');
const mapsRoutes = require('./routes/maps.routes');

const app = express();

// bcrypt for password hashing, comparing password
connectToDb();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }))
app.use(cookirParser());

app.get("/", (req, res) => {
    res.send("Hello World");
})
app.use('/users', userRoutes);
app.use('/captains', captainRoutes);
app.use('/maps', mapsRoutes);
module.exports = app;

Map Controller.js:

const getAutoCompleteSuggestionsController = async (req, res, next) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }
    const { input } = req.body;
    console.log("input", input);
    try {
        const suggestions = await mapService.getAutoCompleteSuggestions(input);
        console.log("suggestions", suggestions);
        res.status(200).json(suggestions);
    } catch (error) {
        res.status(500).json({ message: 'Internal server error' });
    }
}

module.exports = {
    getAutoCompleteSuggestionsController
};

Map service file:

const getAutoCompleteSuggestions = async (input) => {
try {
console.log("Input:", input);

if (!input) {
    return { success: false, error: "Query is required" };
}

const apiKey = process.env.GOOGLE_MAPS_API;
const url = `:autocomplete`;
const requestData = {
    input: input,
    languageCode: "en",
    regionCode: "US",
};

const response = await axios.post(url, requestData, {
    headers: { 
        "Content-Type": "application/json",
        "X-Goog-Api-Key": apiKey,
        "X-Goog-FieldMask": "places.displayName,places.id"
    }
});
console.log("Response:", response);

if (response.data && response.data.places) {
    return {
        success: true,
        suggestions: response.data.suggestions.map(place => ({
            name: place.displayName.text,
            placeId: place.id
        }))
    };
} else {
    return {
        success: false,
        error: "No suggestions found"
    };
}
} catch (error) {
  return {
    success: false,
    error: error.message
};
}
};
module.exports = {
   getAutoCompleteSuggestions
};

I am developing a node.js API with using express and mongodb, I am using google places api with autocomplete but getting status code 400 error.

Why google place api not giving me google suggestions as per my needs, check my postman, I also send bearer token in headers and inside body - raw I pasted this query in json: {"input": "Athreya Hospital"}

App.js file, check Map route:

const dotenv = require("dotenv");
dotenv.config();
const express = require("express");
const cors = require('cors');
const cookirParser = require('cookie-parser');
const connectToDb = require('./db/db');
const userRoutes = require('./routes/user.routes');
const captainRoutes = require('./routes/captain.routes');
const mapsRoutes = require('./routes/maps.routes');

const app = express();

// bcrypt for password hashing, comparing password
connectToDb();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }))
app.use(cookirParser());

app.get("/", (req, res) => {
    res.send("Hello World");
})
app.use('/users', userRoutes);
app.use('/captains', captainRoutes);
app.use('/maps', mapsRoutes);
module.exports = app;

Map Controller.js:

const getAutoCompleteSuggestionsController = async (req, res, next) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }
    const { input } = req.body;
    console.log("input", input);
    try {
        const suggestions = await mapService.getAutoCompleteSuggestions(input);
        console.log("suggestions", suggestions);
        res.status(200).json(suggestions);
    } catch (error) {
        res.status(500).json({ message: 'Internal server error' });
    }
}

module.exports = {
    getAutoCompleteSuggestionsController
};

Map service file:

const getAutoCompleteSuggestions = async (input) => {
try {
console.log("Input:", input);

if (!input) {
    return { success: false, error: "Query is required" };
}

const apiKey = process.env.GOOGLE_MAPS_API;
const url = `https://places.googleapis/v1/places:autocomplete`;
const requestData = {
    input: input,
    languageCode: "en",
    regionCode: "US",
};

const response = await axios.post(url, requestData, {
    headers: { 
        "Content-Type": "application/json",
        "X-Goog-Api-Key": apiKey,
        "X-Goog-FieldMask": "places.displayName,places.id"
    }
});
console.log("Response:", response);

if (response.data && response.data.places) {
    return {
        success: true,
        suggestions: response.data.suggestions.map(place => ({
            name: place.displayName.text,
            placeId: place.id
        }))
    };
} else {
    return {
        success: false,
        error: "No suggestions found"
    };
}
} catch (error) {
  return {
    success: false,
    error: error.message
};
}
};
module.exports = {
   getAutoCompleteSuggestions
};

Share Improve this question edited Mar 18 at 15:08 James Z 12.3k10 gold badges27 silver badges47 bronze badges asked Mar 18 at 8:17 user2568391user2568391 217 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

You are sending a request to Place Autocomplete with a X-Goog-FieldMask header that is only valid for search requests (e.g. Text Search).

The correct X-Goog-FieldMask for Place Autocomplete, assuming you want to get only each prediction's Place ID and single-line description, would be

X-Goog-FieldMask: suggestions.placePrediction.text.text,suggestions.placePrediction.placeId

However, chances are that's not really what you want. For one thing, adding X-Goog-FieldMask requests makes them neither cheaper nor faster; you can do it but there is no strong reason to do it.

It seems to me more likely that you'd want to first take the Place ID for Autocomplete when the user selects a place and then send a Place Details request for that Place ID.

In that case, you also need a different X-Goog-FieldMask header for Place Details requests; assuming you want to get only a place's Place ID and name, the correct value would be

X-Goog-FieldMask: id,displayName.text

Note that the displayName field will trigger the SKU: Places API Place Details Pro price if not using Autocomplete Sessions. If using sessions, the displayName field will trigger the (higher cost) SKU: Places API Place Details Enterprise + Atmosphere. See Pricing examples for more details.

本文标签: nodejsGoogle Places APIPlaces APIAutoComplete Error 400 (Bad Request)Stack Overflow