Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement FormData.get and FormData.getAll #388

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jdeniau
Copy link

@jdeniau jdeniau commented Jun 7, 2018

The implementation is maybe very simplistic but it may do the job

See:

@coveralls
Copy link

coveralls commented Jun 7, 2018

Coverage Status

Coverage increased (+0.1%) to 98.148% when pulling 48d93c2 on jdeniau:jd-feat-getAndGetAll into b16916a on form-data:master.

@jdeniau
Copy link
Author

jdeniau commented Jun 7, 2018

Th appveyor test is failing randomly I don't know why (I tried to amend and push another time, and it failed on another test case)

@srph srph mentioned this pull request Jul 19, 2018
@yordis
Copy link

yordis commented Oct 17, 2018

@alexindigo could you take a look to this mate. I need this feature to be able to publish a package and would be great if we could have it.

It seems that the Appveyor is failing because of permissions issues, but the PR is fine.

@@ -31,6 +31,7 @@ function FormData(options) {
this._overheadLength = 0;
this._valueLength = 0;
this._valuesToMeasure = [];
this._entryList = [];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused with this.

You use an array as the data structure but then you use it as an object

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad !
It works because Javascript Array are objects, and thus it become attribute of an object, I will change this to a map ;)

@yordis
Copy link

yordis commented Oct 17, 2018

@jdeniau actually I would use a list for this and create a list of objects.

I know that from data structure makes sense but following the spec I believe that append do not remove the previous one, if you read the spec when you append it keeps adding entries even when they could have the same name.

From documentation

Each FormData object has an associated entry list (a list of entries). It is initially the empty list.
An entry consists of a name and a value.

So maybe is better to have a list of objects

[
 { name: 'hello', value: 'world'}
]

I am trying to finish the spec and probably maybe would be better if you change the current implementation

So far,

function createEntry(name, value, filename) {
  // TODO: handle Blob and File
  // Related to https://xhr.spec.whatwg.org/#concept-formdata-entry

  // Case 1:
  // If value is a Blob object and not a File object, then set value to a new
  // File object, representing the same bytes, whose name attribute value is
  // "blob".

  // Case 2:
  // If value is (now) a File object and filename is given, then set value to a
  // new File object, representing the same bytes, whose name attribute value
  // is filename.

  var entry = {
    name: name,
    value: value,
  };

  return entry;
}

I created this functions because it seems that we will need to do some complex stuff with the entries https://xhr.spec.whatwg.org/#concept-formdata-entry

So basically for now you could do this._entries.push( createEntry(name, value, filename );

The filename come from the API, on set and append you will have two cases for the function

  void append(USVString name, USVString value);
  void append(USVString name, Blob blobValue, optional USVString filename);

So one expects just a value and the other one expects a File/Blob I guess.

lib/form_data.js Outdated
@@ -31,6 +31,7 @@ function FormData(options) {
this._overheadLength = 0;
this._valueLength = 0;
this._valuesToMeasure = [];
this._entryList = {};
Copy link

@yordis yordis Oct 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this._entryList = {};
this._entryList = [];

We need to use a list rather than an array. The current spec allow you to append to the list multiple values for the same key

lib/form_data.js Outdated
if (!this._entryList[field]) {
this._entryList[field] = [];
}
this._entryList[field].push(value);
Copy link

@yordis yordis Oct 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Append an object with the following shape

{ name: '', value: '' }

append do not remove previous entry, just do an append on the list.

Suggested change
this._entryList[field].push(value);
// move this function out of this scope, this is just so you have an idea about it.
function createEntry(name, value, filename) {
// TODO: handle Blob and File
// Related to https://xhr.spec.whatwg.org/#concept-formdata-entry
// Case 1:
// If value is a Blob object and not a File object, then set value to a new
// File object, representing the same bytes, whose name attribute value is
// "blob".
// Case 2:
// If value is (now) a File object and filename is given, then set value to a
// new File object, representing the same bytes, whose name attribute value
// is filename.
var entry = {
name: name,
value: value,
};
return entry;
}
const entry = createEntry(field, value, filename);
this._entryList.push(entry);

lib/form_data.js Outdated
};

FormData.prototype.get = function(field) {
return this._entryList[field] ? this._entryList[field][0] : null;
Copy link

@yordis yordis Oct 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the spec

The get(name) method, when invoked, must return the value of the first entry whose name is name from the context object’s entry list, and null otherwise.

Do an Array.find

Suggested change
return this._entryList[field] ? this._entryList[field][0] : null;
var foundEntry = this._entryList.find(function(entry) {
return entry.name === field;
});
return foundEntry === undefined ? null: foundEntry.value

lib/form_data.js Outdated
};

FormData.prototype.getAll = function(field) {
return this._entryList[field] || [];
Copy link

@yordis yordis Oct 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the spec

The getAll(name) method, when invoked, must return the values of all entries whose name is name, in order, from the context object’s entry list, and the empty list otherwise.

Do an Array.filter in the list.

Suggested change
return this._entryList[field] || [];
return this._entryList.reduce(function (acc, entry) {
if(entry.name === field) {
acc.push(entry.value);
}
return acc;
}, []);

@yordis
Copy link

yordis commented Oct 17, 2018

Hey @jdeniau, for me to be able to finish the other APIs I will need the changes that I suggest. Would be better for me to work on top what you did already rather than duplicating the work.

@jdeniau
Copy link
Author

jdeniau commented Oct 17, 2018

Looks good to me, I will work on this, but I did not quite well understand the [constructing the entry list(https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set) part 🤔

@yordis
Copy link

yordis commented Oct 17, 2018

@jdeniau well that one is for the web actually.

FormData constructor expects an optional form.

If you pass a form you need to loop throw the list of inputs under that form and do an append of the entry where the entry name is the field name and the value is the field value based on some weird stuff.

But this code is only for NodeJS unless you are trying to monkey patch that as well.

lib/form_data.js Outdated Show resolved Hide resolved
lib/form_data.js Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants