Git Product home page Git Product logo

ember-cli-form-data's Introduction

ember-cli-form-data

This Ember-CLI addon adds file uploads through FormData to the Ember Data

Install

ember install ember-cli-form-data

Usage

Add a file field on the model

// models/post.js

export default DS.Model.extend({
  attachment: DS.attr('file'),
  ...
});

Add the FormDataMixin to your post adapter. Run ember g adapter post if you don't have the adapter.

// adapters/post.js

import FormDataAdapterMixin from 'ember-cli-form-data/mixins/form-data-adapter';

export default ApplicationAdapter.extend(FormDataAdapterMixin, {
  // Adapter code
});

Then you can use an <input type='file' id='file-field'/> to send the attachment:

var file = document.getElementById('file-field').files[0];
model.set('attachment', file);
model.save();

This will send the attachment and all other attributes as a FormData object.

Flatten FormData fields

Some api's desire the form data fields to not include the root object name. For example, the default adapter behavior would result in post[title] in your serialized data. If your api instead expects just title, add disableRoot: true to remove the model name from the fields.

Other Resources

Thanks

This addon was inspired by Matt Beedle's blog post http://blog.mattbeedle.name/posts/file-uploads-in-ember-data/

ember-cli-form-data's People

Contributors

3h15 avatar bardzusny avatar chbonser avatar ember-tomster avatar funtusov avatar gufnz avatar jeffreybiles avatar loganrosen avatar malina avatar rmachielse avatar stopdropandrew avatar yratanov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ember-cli-form-data's Issues

How to update thumbnail preview

I'm really happy with using ember-cli-form-data thanks!

Maybe this doesn't have much to do directly with this addon, but I was wondering if there was a standard way in my form of updating a preview thumbnail image when a new file is selected in the input file type.

Not everything should be FormData

The issue is that certain fields don't need to be FormData, only the attributes with the file transform.

I'm seeing issues with certain libraries that expect arrays to come over as arrays, and not comma separated strings. This happens with hasManys when you POST an attribute as an array.

Seems like there should be a type check here.

`hash` is `undefined` in `ajaxOptions`

In some cases, the hash argument in ajaxOptions is undefined. Wouldn't it be better to first call the _super method and then modify the result ? Something like:

ajaxOptions: function(url, type, options) {
  var hash = this._super.apply(this, arguments);

  if (hash.data && this.formDataTypes.contains(type)) {
    hash = this._setBaseFor(url, type, hash, this);
    hash = this._setFormDataFor(hash);
    hash = this._setHeadersFor(hash);
  }

  return hash;
},

What do you think ?

payload is not json

Hi,
Thank you for your effort but I am having some trouble,
I have simple form with just one field, on POST request instead of json I am getting something like:
------WebKitFormBoundary57pDcluXygbVh10c
Content-Disposition: form-data; name="config[myPropertyName]"; filename="test.txt"
Content-Type: application/octet-stream

------WebKitFormBoundary57pDcluXygbVh10c--
If I inspect file object in console it looks ok, even in my model it is there.

'file' attribute is not an object

After installing and setting up the ember-cli-form-data and adding "avatar: DS.attr('file')" to the user model in my case, when inspecting the browser with the Ember inspector I do not get the "avatar" property in the form of an Object.
original

Please also find attached all the settings from the models/user.js, adapters/user.js. fistures/user.js, controller.js and template.hbs.

I'm using Ember CLI Mirage fixtures, Ember Data 2.2.0, and Ember 2.2.0. Any idea what could happen?

adapter
controller
fixtures
model
template

Thank you!

Add support for Ember 4

In order to work with Ember 4 the method ajaxOptions should return FormData object in 'body' field instead of 'data'. Here is the code:

ajaxOptions: function (url, type, options) {
    var data;

    if (options && 'data' in options) {
      data = options.data;
    }

    var hash = this._super.apply(this, arguments);

    if (
      typeof FormData !== 'undefined' &&
      data &&
      this.formDataTypes.indexOf(type) >= 0
    ) {
      hash.processData = false;
      hash.contentType = false;
      if (typeof hash.headers !== 'undefined') {
        delete hash.headers['content-type'];
      }
      hash.body = this._getFormData(data);
    }
    return hash;
  }

version is not updated

Source files are updated, but version is not updated, version of npm package is still the same 1.1.0 (published a year ago).
Please publish the changes.

adapter extracting incorrect root

I'm unable to save a model due to ember-cli-form-data extracting the incorrect root.

Model:


export default Model.extend({
  title: attr(),
  image: attr('file'),
  description: attr(),
  thumbnail: attr(),
  createdAt: attr('date')
});

Controller:


import Ember from 'ember';

export default Ember.Controller.extend({
  actions: {
    submit() {

      const model = this.store.createRecord('image', {
        title: this.get('title'),
        description: this.get('description')
      });

      const image = document.getElementById('image').files[0];
      model.set('image', image);
      model.save();

    }
  }
});

This is the resulting payload:

------WebKitFormBoundarydHjcL7c0dAoCTjNp
Content-Disposition: form-data; name="title[0]"

t
------WebKitFormBoundarydHjcL7c0dAoCTjNp
Content-Disposition: form-data; name="title[1]"

e
------WebKitFormBoundarydHjcL7c0dAoCTjNp
Content-Disposition: form-data; name="title[2]"

s
------WebKitFormBoundarydHjcL7c0dAoCTjNp
Content-Disposition: form-data; name="title[3]"

t
------WebKitFormBoundarydHjcL7c0dAoCTjNp--

Working through the breakpoints I see this in the ember-cli-form-data adapter:

    _getFormData: function _getFormData(data) {
     // data is {title: 'test', description: 'test', image: File}
      var formData = new FormData();
      var root = Object.keys(data)[0]; // root is 'title'


JSON Parse error after upgrading to newer Ruby JSON gem

Hi,

I recently upgraded my Ember app from 3.9 to 3.10, and my Rails app from 4.x to 5.x. My form data used to work fine, but now it does not - it reports a JSON::ParseError.

Looking at the package.json I see that your add-on did not change => I assume the same form data params are being sent to the server.

The Rails gemfile.lock file informs me that the json gem went from 1.8.3 to 2.2.0 (major number change => uh, oh... as we all know ;-)

Given that your add-on stayed the same and the json gem changed a lot tells me that the problem is most likely on their end. I am asking this same question on their "Issues" page; I am asking it here because maybe someone has run into this problem and can help me out. (Obviously, if I get an answer over there I will post it here so that maybe it will help others.)

My form isn't that complicated; just the usual stuff with a user-image capability. Also, I figure that this add-on must be used a lot with the latest Ruby/Rails JSON gem => seems like this should "just work" like it used to.

Below is the output I am seeing. Any help will be greatly appreciated, as I am stuck with not being able to create/update users. BTW, I tried backing off the JSON gem from 2.2.0 to 1.8.3 but could not do it due to a variety of bundler errors.

Thanks,
Larry

===============================
JSON::ParserError at /spa/users

785: unexpected token at '------WebKitFormBoundaryyBVIQZp7P07Edby7
Content-Disposition: form-data; name="user[state]"

MA
------WebKitFormBoundaryyBVIQZp7P07Edby7
Content-Disposition: form-data; name="user[district]"

3
------WebKitFormBoundaryyBVIQZp7P07Edby7
Content-Disposition: form-data; name="user[username]"

joesmith
------WebKitFormBoundaryyBVIQZp7P07Edby7
Content-Disposition: form-data; name="user[email]"

[email protected]
------WebKitFormBoundaryyBVIQZp7P07Edby7
Content-Disposition: form-data; name="user[password]"

pword
------WebKitFormBoundaryyBVIQZp7P07Edby7
Content-Disposition: form-data; name="user[first_name]"

Joe
------WebKitFormBoundaryyBVIQZp7P07Edby7
Content-Disposition: form-data; name="user[last_name]"

Smith
------WebKitFormBoundaryyBVIQZp7P07Edby7
Content-Disposition: form-data; name="user[password_confirmation]"

pword
------WebKitFormBoundaryyBVIQZp7P07Edby7--
'

json (2.2.0) lib/json/common.rb, line 156

  151     #   additions even if a matching class and create_id was found. This option
  152     #   defaults to false.
  153     # * *object_class*: Defaults to Hash
  154     # * *array_class*: Defaults to Array
  155     def parse(source, opts = {})
> 156       Parser.new(source, opts).parse
  157     end
  158   
  159     # Parse the JSON document _source_ into a Ruby data structure and return it.
  160     # The bang version of the parse method defaults to the more dangerous values
  161     # for the _opts_ hash, so be sure only to parse trusted _source_ documents.

App backtrace

Full backtrace

  • json (2.2.0) lib/json/common.rb:156:in `parse'
  • activesupport (5.2.3) lib/active_support/json/decoding.rb:23:in `decode'
  • actionpack (5.2.3) lib/action_dispatch/http/parameters.rb:12:in `block in module:Parameters'
  • actionpack (5.2.3) lib/action_dispatch/http/parameters.rb:112:in `parse_formatted_parameters'
  • actionpack (5.2.3) lib/action_dispatch/http/request.rb:381:in `block in POST'
  • rack (2.0.7) lib/rack/request.rb:59:in `fetch_header'
  • actionpack (5.2.3) lib/action_dispatch/http/request.rb:380:in `POST'
  • actionpack (5.2.3) lib/action_dispatch/http/parameters.rb:55:in `parameters'
  • actionpack (5.2.3) lib/action_controller/metal/params_wrapper.rb:290:in `_wrapper_enabled?'
  • actionpack (5.2.3) lib/action_controller/metal/params_wrapper.rb:244:in `process_action'
  • activerecord (5.2.3) lib/active_record/railties/controller_runtime.rb:24:in `process_action'
  • actionpack (5.2.3) lib/abstract_controller/base.rb:134:in `process'
  • actionview (5.2.3) lib/action_view/rendering.rb:32:in `process'
  • actionpack (5.2.3) lib/action_controller/metal.rb:191:in `dispatch'
  • actionpack (5.2.3) lib/action_controller/metal.rb:252:in `dispatch'
  • actionpack (5.2.3) lib/action_dispatch/routing/route_set.rb:52:in `dispatch'
  • actionpack (5.2.3) lib/action_dispatch/routing/route_set.rb:34:in `serve'
  • actionpack (5.2.3) lib/action_dispatch/routing/mapper.rb:18:in `block in class:Constraints'
  • actionpack (5.2.3) lib/action_dispatch/routing/mapper.rb:48:in `serve'
  • actionpack (5.2.3) lib/action_dispatch/journey/router.rb:52:in `block in serve'
  • actionpack (5.2.3) lib/action_dispatch/journey/router.rb:35:in `serve'
  • actionpack (5.2.3) lib/action_dispatch/routing/route_set.rb:840:in `call'
  • bullet (6.0.0) lib/bullet/rack.rb:12:in `call'
  • exception_notification (4.3.0) lib/exception_notification/rack.rb:41:in `call'
  • mobvious (0.3.2) lib/mobvious/manager.rb:25:in `call'
  • warden (1.2.8) lib/warden/manager.rb:36:in `block in call'
  • warden (1.2.8) lib/warden/manager.rb:34:in `call'
  • rack (2.0.7) lib/rack/tempfile_reaper.rb:15:in `call'
  • rack (2.0.7) lib/rack/etag.rb:25:in `call'
  • rack (2.0.7) lib/rack/conditional_get.rb:38:in `call'
  • rack (2.0.7) lib/rack/head.rb:12:in `call'
  • actionpack (5.2.3) lib/action_dispatch/http/content_security_policy.rb:18:in `call'
  • rack (2.0.7) lib/rack/session/abstract/id.rb:232:in `context'
  • rack (2.0.7) lib/rack/session/abstract/id.rb:226:in `call'
  • actionpack (5.2.3) lib/action_dispatch/middleware/cookies.rb:670:in `call'
  • activerecord (5.2.3) lib/active_record/migration.rb:559:in `call'
  • actionpack (5.2.3) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
  • activesupport (5.2.3) lib/active_support/callbacks.rb:98:in `run_callbacks'
  • actionpack (5.2.3) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
  • actionpack (5.2.3) lib/action_dispatch/middleware/executor.rb:14:in `call'
  • better_errors (2.5.1) lib/better_errors/middleware.rb:84:in `protected_app_call'
  • better_errors (2.5.1) lib/better_errors/middleware.rb:79:in `better_errors_call'
  • better_errors (2.5.1) lib/better_errors/middleware.rb:57:in `call'
  • actionpack (5.2.3) lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'
  • actionpack (5.2.3) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
  • railties (5.2.3) lib/rails/rack/logger.rb:38:in `call_app'
  • railties (5.2.3) lib/rails/rack/logger.rb:28:in `call'
  • sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in `call'
  • actionpack (5.2.3) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
  • actionpack (5.2.3) lib/action_dispatch/middleware/request_id.rb:27:in `call'
  • rack (2.0.7) lib/rack/method_override.rb:22:in `call'
  • rack (2.0.7) lib/rack/runtime.rb:22:in `call'
  • activesupport (5.2.3) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
  • actionpack (5.2.3) lib/action_dispatch/middleware/executor.rb:14:in `call'
  • actionpack (5.2.3) lib/action_dispatch/middleware/static.rb:127:in `call'
  • rack (2.0.7) lib/rack/sendfile.rb:111:in `call'
  • rack-cors (1.0.3) lib/rack/cors.rb:95:in `call'
  • railties (5.2.3) lib/rails/engine.rb:524:in `call'
  • railties (5.2.3) lib/rails/railtie.rb:190:in `method_missing'
  • rack (2.0.7) lib/rack/urlmap.rb:68:in `block in call'
  • rack (2.0.7) lib/rack/urlmap.rb:53:in `call'
  • puma (3.12.1) lib/puma/configuration.rb:227:in `call'
  • puma (3.12.1) lib/puma/server.rb:660:in `handle_request'
  • puma (3.12.1) lib/puma/server.rb:474:in `process_client'
  • puma (3.12.1) lib/puma/server.rb:334:in `block in run'
  • puma (3.12.1) lib/puma/thread_pool.rb:135:in `block in spawn_thread'

Base64 encoding

Is there a way to somehow access or convert the file upload as base64, and use that as the attribute when making a request?

file attribute undefined

Hello!

I need some help getting this working, if you would be so kind...

I'm trying to allow users to upload an image of their insurance card, but as you can see in the model an attribute whose type is 'file' shows up as undefined, and I think it's not finding the Mixin?

I'm using Ember Data 2.14.2.

I'm pretty new to Ember. Any help would be greatly appreciated.

screen shot 2017-08-01 at 4 10 49 pm

Server response

So from the readme it's obvious what gets set on the attribute, but what should the server respond with to send the file to the browser? Should there be a second attribute for the url (or image base64 data)?

consider having better handling of array values

Currently, array values get serialized as comma-separated strings. This is less than ideal since the only real reason to use FormData over json is to handle files, and servers have a hard time figuring out your binary from strings like "[object Object], [object Object]".

Therefore, please consider changing:
https://github.com/funtusov/ember-cli-form-data/blob/master/addon/mixins/form-data-adapter.js#L18

Ember.keys(data[root]).forEach(function(key) {
  if (typeof data[root][key] !== 'undefined') {
    formData.append(root + "[" + key + "]", data[root][key]);
  }
});

to...

Ember.keys(data[root]).forEach(function(key) {
  if (Ember.isArray(data[root][key])) {
    data[root][key].forEach(function(value) { 
      formData.append(root + "[" + key + "][]", value);
    });
  } else if (typeof data[root][key] !== 'undefined') {
    formData.append(root + "[" + key + "]", data[root][key]);
  }
});

If this is something we're interested in doing, please let me know and I will submit a PR after I fail my presentation on June 2nd

Empty file being uploaded

I'm trying to implement ember-cli-form-data to upload a file to my rails backend server which is using the CarrierWave gem.

I followed your guidelines step by step but cannot get it to work properly.

In the request, the file is empty for some weird reason.

file => {}

I'm using the following versions:

Ember:      1.13.7
Ember data: 1.13.8

Could it be that ember-cli-form-data doesn't work for these versions?

need to update code to work with new version of ember data

I do not have time in the moment to look through the code and make a pr and what not. so I am just making a note here for me to come back to.
when I add the mixin to my adapter it messes up the serialization of other attributes. I have user_ids that should be headed up to the server as an array of strings like so ["1", "2", "3"] but actually gets sent up as just a string like this: "1,2,3".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.