mapbox / mapbox-sdk-js

A JavaScript client to Mapbox services, supporting Node, browsers, and React Native
Other
718 stars 186 forks source link

Trouble trying to create a Tileset Source. #406

Open SpyAdrian opened 3 years ago

SpyAdrian commented 3 years ago

Hi !

I'm trying to use the createTilesetSource function in the services section, and it returns me an error:

No file data in request. Expected 1 file named "file".

I'm using it like that :

import MapboxTilesets from "@mapbox/mapbox-sdk/services/tilesets";
const tilesetsClient = MapboxTilesets({ accessToken });

and

async CreateTilesetSource() {
    console.log("Create A Tileset Source");

    const tilesetId = "newTileSet";

    const data = await this.GetJsonFile();
    const geoJsonData = GeoJson.parse(data, { Point: ["lat", "lng"] });
    const blobFile = new Blob([geoJsonData], { type: "application/json" });

    return new Promise((resolve) => {
        tilesetsClient
            .createTilesetSource({
                id: tilesetId,
                file: blobFile,
            })
            .send()
            .then((res) => {
                const tilesetSource = res.body;
                console.log(tilesetSource);
            })
            .catch((res) => {
                console.log("--- CATCH ERROR ! ---");
                console.log(res.message);
                resolve(null);
            })
            .done();
    });
}

Thank you in advance ! : )

maxwell-oroark commented 3 years ago

@andria01 might be other issues but from what I can see you might need to drop done() I don't see that method anywhere in the docs

SpyAdrian commented 3 years ago

@maxwell-oroark Thank you for your answer, but that doesn't seem to be the problem, I tried with or without I get the same error from the API. I think the problem is that I can't give the file properly to the API correctly.

SpyAdrian commented 3 years ago

Now I'm trying another way to do it using react-native-fs, and I keep getting this error. Here is the way :

Create a Tileset Source

async createTilesetSource(dataJson) {
        console.log("Create A Tileset Source");

        const geoJsonData = GeoJson.parse(dataJson, { Point: ["lat", "lng"] });
        const path = await this._localStorageController.writeFile("features.geojson", geoJsonData);
        console.log("path : " + path);

        return new Promise((resolve) => {
            const body = new FormData();
            body.append("file", '@"' + path + '"');

            fetch(
                "https://api.mapbox.com/tilesets/v1/sources/andria01/hello-world?access_token=" + accessToken,
                {
                    body,
                    headers: {
                        "Content-Type": "multipart/form-data",
                    },
                    method: "POST",
                }
            )
                .then((res) => res.json())
                .then((res) => {
                    console.log(res);
                    resolve(res);
                })
                .catch((res) => {
                    console.log("--- CATCH ERROR ! ---");
                    console.log(res.message);
                    resolve(null);
                })
                .done();
        });
    }

Writing a file

writeFile(fileName, content) {
        console.log("Write File");

        const path = RNFS.DocumentDirectoryPath + "/" + fileName;

        return new Promise((resolve) => {
            RNFS.writeFile(path, content)
                .then((res) => {
                    console.log("File Written");
                    resolve(path);
                })
                .catch((res) => {
                    console.log("--- CATCH ERROR ! ---");
                    console.log(res.message);
                    resolve(null);
                })
                .done();
        });
    }

Output

[Sat Jan 30 2021 11:45:42.190]  LOG      Create A Tileset Source
[Sat Jan 30 2021 11:45:42.200]  LOG      Write File
[Sat Jan 30 2021 11:45:42.250]  LOG      File Written
[Sat Jan 30 2021 11:45:42.250]  LOG      path : /data/user/0/com.appName/files/features.geojson
[Sat Jan 30 2021 11:45:42.235]  LOG      {"message": "No file data in request. Expected 1 file named \"file\"."}

If someone can help me, thank you in advance ! : )

kylebaskin commented 3 years ago

@andria01 Did you ever solve this? I'm having the same problem.

SpyAdrian commented 3 years ago

@kylebaskin Sorry but I didn't fix it yet. If you have a solution let me know.

kylebaskin commented 3 years ago

@andria01 I found a workaround for my purposes, but I'm not sure it'll translate to your project.

Either way, here's a short description of my project and what I needed to do.

Description:
(I'm not using react or react native, just vanilla javascript and Mapbox GL JS with some mapbox-sdk stuff to make backend edits) The main goal was to update my map programmatically by taking csv data from a file upload, add that data to an existing dataset, then export that dataset to a tileset which is included in my map. I found out that this implementation wasn't the best idea after digging into Mapbox GL JS a bit more, and I'll briefly explain why.

What I needed to do: Instead of updating the dataset to update the tileset to update the map, I found out I could only update the dataset to update the map. In short, I was trying to stitch the dataset, tileset, and map style all together using the mapbox-sdk on my mapbox account and then simply show the map on my site; however, what ended up being quicker/easier was to update only the dataset with the mapbox-sdk, then stitch together the updated dataset and map style locally on my site with Mapbox GL JS.

I understand this isn't a super elegant answer, so if this is something that you believe could help you out, I'd be happy to discuss further, go into more depth, and add some examples of what I did.

SpyAdrian commented 3 years ago

Hi @kylebaskin, thanks for your reply, and sorry for the late reply. I have taken into consideration the solution you proposed. I thought about it to see if I could integrate it into my project, but I'm afraid it can't.

ThomasMartinKearns commented 3 years ago

I am getting this error from Postman, using a datafile, I had used previously successfully.

contents of data file

{"type":"Feature","id":1,"geometry":{"type":"Point","coordinates":[115.7,12.2]},"properties":{"name":"cool feature"}} {"type":"Feature","id":2,"geometry":{"type":"Point","coordinates":[125.7,12.2]},"properties":{"name":"neat feature"}} {"type":"Feature","id":3,"geometry":{"type":"Point","coordinates":[135.7,12.2]},"properties":{"name":"bad place"}} {"type":"Feature","id":4,"geometry":{"type":"Point","coordinates":[105.7,12.2]},"properties":{"name":"good place"}}

NIMS-Database commented 3 years ago

@andria01 @kylebaskin
Don't know if you find other solution, but in my case, getting exactly same error as you, it was a syntax case after all... To post a file with Curl, use the -F command-line options and start the data with the @ symbol followed by the file name. To send multiple files, repeat the -F option several times. Example:
curl -X POST "https://api.mapbox.com/tilesets/v1/sources/{username}/{id}?access_token={your_token}" -F file="@data.json" -H "Content-Type: multipart/form-data"

So, in my case it was "@" symbol in front of each file.

I saw in your code, around this line: body.append("file", '@"' + path + '"'); please notice the double quote does not include @ symbol in the filename, so i think it should be: body.append("file", '"@' + path + '"');

Hope this help.