5

The documentation is vague: https://www.drupal.org/docs/8/modules/json-api/working-with-files-post

I am trying to upload an image following the sample code given for uploading a "document" on above page.

Simplified example:
Given an admin user "bot" and a base-64 encoded qr code.

I create the json payload following the example in the documentation

{
  "data": {
      "type": "file--image",
      "attributes:": {
          "title": "QR Code",
          "uri": "public://folder/qr-code.png",
          "data": "iVBORw0KGgoAAAANSUhEUgAAAG8AAABvAQMAAADYCwwjAAAABlBMVEUAAAD///+l2Z/dAAAAAnRSTlP//8i138cAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAEsSURBVDiN1dS7jcMwDABQGirU5RYQoDXUaSV7AX8WsFdSxzUCeAGrUyGYRzuJ79KIKoIDTnCRVyj8gBTQ24H/wQ1gQNNCBrAiI+UOafRmoAqG48eSTKur2Gq4+VzJ3q/x190SKbfOLpivJAvkejs0/F3lF8hnh9yFn8YWuIEBR7tXs6ugJkIVEzSPrIqMBF94By72DFTmpteJVAxXoBI5RK9Nz4lpmbtTCx2FdGdWZRLmHuzo1/m8K5DWKeWB6001NEOg0dHrbombt9wfHu8GrcgYeEjuN00Lkky0m1eEdkoVTIa3rHfQBCuST6TzH0DmMbGBo/AukEjehSHkLtmYrExeyWNioXmWL1EDd34GW0XPneQ3h2Tym0OKh/Y5sUU+9hfcOmqZf/YCf4zfOAszBtzxUOsAAAAASUVORK5CYII="
      }
  }
}

Which translates into this curl command

curl \
--user bot:bot \
--header 'Accept: application/vnd.api+json' \
--header 'Content-type: application/vnd.api+json' \
--request POST http://drupalvm.test/jsonapi/file/image \
--data-binary '{"data": {"type": "file--image", "attributes:": {"title": "QR Code", "uri": "public://folder/qr-code.png", "data": "iVBORw0KGgoAAAANSUhEUgAAAG8AAABvAQMAAADYCwwjAAAABlBMVEUAAAD///+l2Z/dAAAAAnRSTlP//8i138cAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAEsSURBVDiN1dS7jcMwDABQGirU5RYQoDXUaSV7AX8WsFdSxzUCeAGrUyGYRzuJ79KIKoIDTnCRVyj8gBTQ24H/wQ1gQNNCBrAiI+UOafRmoAqG48eSTKur2Gq4+VzJ3q/x190SKbfOLpivJAvkejs0/F3lF8hnh9yFn8YWuIEBR7tXs6ugJkIVEzSPrIqMBF94By72DFTmpteJVAxXoBI5RK9Nz4lpmbtTCx2FdGdWZRLmHuzo1/m8K5DWKeWB6001NEOg0dHrbombt9wfHu8GrcgYeEjuN00Lkky0m1eEdkoVTIa3rHfQBCuST6TzH0DmMbGBo/AukEjehSHkLtmYrExeyWNioXmWL1EDd34GW0XPneQ3h2Tym0OKh/Y5sUU+9hfcOmqZf/YCf4zfOAszBtzxUOsAAAAASUVORK5CYII="}}}' 

This results in an error:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'uri' cannot be null

What am I doing wrong?

I am using a local Drupal instance generated by https://github.com/geerlingguy/drupal-vm#quick-start-guide on Mac Sierra 10.12.6

It is

Drupal core 8.5.3

Includes: Automated Cron, BigPipe, Block, Breakpoint, CKEditor, Color, Comment, Configuration Manager, Contact, Contextual Links, Custom Block, Custom Menu Links, Database Logging, Datetime, Field, Field UI, File, Filter, HTTP Basic Authentication, Help, History, Image, Internal Dynamic Page Cache, Internal Page Cache, Link, Menu UI, Node, Options, Path, Quick Edit, RDF, Search, Serialization, Shortcut, System, Taxonomy, Text, Text Editor, Toolbar, Tour, Update Manager, User, Views, Views UI

With the following Modules

  • File Entity (fieldable files) 8.x-2.0-beta6
  • JSON API 8.x-1.18
  • JSON API File 8.x-1.1
  • Token 8.x-1.3

(And with the core HTTP Basic Authentication module enabled)

2

2 Answers 2

2

Here is a javaScript version that may help after alot of trial and error I could only get "entity/file?_format=hal_json" to work aka "file_entity" module.

the following "bace64" = iVBORw0KGgoAAAANSUhEUgAAAG8AAABvA.....

uploadDrupalImage(bace64) {
  // Could only get hal_json to work.
  var dataToPost = '{"_links": {"type": {"href": ' + JSON.stringify(this.baceUrl + 'rest/type/file/image') + '}},"filename": [{"value": "' + this.state.file.name + '"}],"data":[{"value": "' + bace64 + '"}]}';
  var url = this.baceUrl + 'entity/file?_format=hal_json';
  fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/hal+json',
      'X-CSRF-Token': this.state.csrf_token,
      'Authorization': this.state.basicAuth,
    },
    body: dataToPost
  }).then(response => response.json()).then(data => {
    if (data) {
      this.setState({uploadedFile: data});
      if (data.fid) {
        //console.log(data.fid[0].value);
        this.setState({fid: data.fid[0].value});
      }
    }
  }).catch(err => console.error(err.toString()));
  return false;
}

taken from (when i was just learning react so be kind lol) https://github.com/taggartj/Drupa_react_REST_examples/blob/master/src/components/drupal/DrupalCreateArticleWithImageBasicAuth.js

1

I found another example with axios buried in the issue queue:

Credit to Hygglo on drupal.org, but I'm reposting here because having this example saved me from some frustrating debugging, and hopefully it can help more people:

onDrop = (acceptedFiles, rejectedFiles) => {
        let file = acceptedFiles[0];

        let filename = file.name;

        var reader = new FileReader();
        reader.readAsArrayBuffer(file);

        reader.onabort = () => console.log('file reading was aborted')
        reader.onerror = () => console.log('file reading has failed')
        reader.onload = () => {

            const arrayStr = reader.result;

            axios.post('/jsonapi/node/application/field_resume',
                arrayStr
                , {
                    headers: {
                        "Content-Type": "application/octet-stream",
                        "Accept": "application/vnd.api+json",
                        "Content-Disposition": 'file; filename="' + filename + '"',
                        'X-CSRF-Token': "HDel-LIL4o709vjgAW6N82Me5wiJ1ZHu_7KHaXN19Vo",
                    }
                }
            )
                .then((response) => {
                    console.log(response);

                })
                .catch(function (error) {
                    console.log(error);


                }.bind(this));
        }

    };

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.