Skip to content
This repository has been archived by the owner on Mar 10, 2020. It is now read-only.

add file does not work in browser (TypeError: target._set is not a function) #344

Closed
nycoliver opened this issue Aug 11, 2016 · 7 comments
Closed
Labels

Comments

@nycoliver
Copy link

Same code as examples/browser-add but adding a file instead of text. It works with text but when adding a file I get index.js:1281 Uncaught TypeError: target._set is not a function

Maybe I am incorrectly forming the buffer? But even the files add code from ipfs-webui throws the same error.

index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <title>JS IPFS API - Example - Browser - Add</title>
    <script src="buffer.js"></script> <!-- feross buffer -->
    <script src="ipfs.js"></script> <!-- js-ipfs-api/dist/index.js -->
    <script src="index.js"></script> <!-- see below -->
  </head>
  <body>
    <h1>JS IPFS API - Add file from the browser</h1>
    <input type="file" id="source">
    <button id="store">create in ipfs</button>
    <div><div>found in ipfs:</div>
      <div id="hash">[ipfs hash]</div>
      <div id="content">[ipfs content]</div>
    </div>
  </body>
</html>

index.js

var ipfs = window.IpfsApi()

function store () {
  const file = document.getElementById('source').files[0];
  const reader = new FileReader();
  reader.onload = function() {

    const buffer = new window.buffer.Buffer(reader.result);
    ipfs.add(buffer, function (err, res) {
      if (err || !res) {
        return console.error('ipfs add error', err, res)
      }

      res.forEach(function (file) {
        console.log('successfully stored', file)
        display(file.path)
      })
    })
  };
  reader.readAsArrayBuffer(file);
}

document.addEventListener('DOMContentLoaded', function() {
  document.getElementById('store').onclick = store
})
@daviddias daviddias added the bug label Aug 12, 2016
@nycoliver nycoliver changed the title Browser TypeError: target._set is not a function files.add does not work in browser (TypeError: target._set is not a function) Aug 26, 2016
@nycoliver nycoliver changed the title files.add does not work in browser (TypeError: target._set is not a function) add file does not work in browser (TypeError: target._set is not a function) Aug 26, 2016
@daviddias
Copy link
Contributor

@nycoliver does https://github.com/ipfs/js-ipfs-api/tree/master/examples/browser-add work for you? If so, could you create an example in the example folders with your experiment so that we can easily replicate it?

@nycoliver
Copy link
Author

browser-add does not work for me. In master branch code throws Uncaught TypeError: fs.readFileSync is not a function and fixes-browser-add branch code throws Error: Payload stream closed prematurely.

The second error is due to js-ipfs-api and webpack incompatibility, as discussed in #335.

I worked around this issue by importing ipfs-api and feross/buffer in script tags and skipping the webpack bundle step. With this workaround the text data successfully adds to ipfs but adding a file with the same code throws Uncaught TypeError: target._set is not a function.

I opened a pull request with an example, please let me know if I can do anything else to help.

@nginnever
Copy link
Contributor

nginnever commented Sep 5, 2016

Bug Update:

Also ran into this trying to add buffer arrays to go-ipfs through js-ipfs-api in the browser.

I get TypeError: target._set is not a function before the request is sent to go-ipfs.

I put a fixed-sized-chunker on the buffer before ipfs.add and found that for any buffer array (including plain text) exactly greater than size 999 bytes we get the target error. Any arbitrary data less than that seems to get sent to go-ipfs for some reason.

var chunk = _chunk.slice(0, 1000)
ipfs.add(chunk, (err, res) => {})

error

var chunk = _chunk.slice(0, 999)
ipfs.add(chunk, (err, res) => {})

no eror

however i'm able to buffer a bunch of zeors with const test = Array.apply(null, Array(20000)).map(Number.prototype.valueOf,0) and buffer and add that just fine.

@nginnever
Copy link
Contributor

nginnever commented Sep 5, 2016

@nycoliver

As a work around to this you can pass a stream to ipfs.add instead of a byte array.

I used Max Ogden's filereader stream to do this https://github.com/maxogden/filereader-stream

e.g.

'use strict'

const fileReaderStream = require('filereader-stream')
const ipfs = window.IpfsApi('localhost', '5001')

// get file from html input
const f = file.files[0]

// use filereader stream as add input
ipfs.add(fileReaderStream(f), (err, res) => {})

Hope this helps!

@nycoliver
Copy link
Author

Upon closer inspection this appears to be a problem with the buffer library, not ipfs. Not sure how we missed that... My example works fine if I webpack the buffers but keep ifps in a script tag.

@nycoliver
Copy link
Author

@dignifiedquire
Copy link
Contributor

I just updated the example on master. Should be working fine now.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants