4

How do I compare FormData object, I am trying to check if the form has been changed or not before sending the ajax request.

But it seems objects cannot be compared. Is there any way to convert it to js Object or an elegant way?

let a = new FormData()
let b = new FormData()

console.log(a === b ) // returns false
0

4 Answers 4

7

I would try this

const a = new FormData();

a.append("username", "Alexander");
a.append("accountnum", 123);

const b = new FormData();

b.append("username", "Alexander");
b.append("accountnum", 123);

let different = false
for (let [key, value] of b.entries()) {
  if (a.get(key) !== value) different = true
}

Or you could try iterating over both objects at the and comparing them, that might be more performant.

JSON.stringify([...a.entries()]) === JSON.stringify([...b.entries()])
Sign up to request clarification or add additional context in comments.

4 Comments

This can definitely be cleaned up a bit, but that seems to me the obvious way to do it.
This won't pick up changes where b has an entry that isn't in a (although that would only be an issue if the form was being dynamically modified)
I was operating under the assumption the form won't change, should iterate over B to improve it. I also assumed that performing get multiple times is faster than iterating over both, worth running some benchmarks.
I might be wrong here, but I think this solution also will not work in cases you have multiple of this same key.
2

You can use formData.entries().

let a = new FormData()
let b = new FormData()

let arr1 = [];
let arr2 = [];

for(let pair of a.entries()) {
    const key = pair[0];
    arr1.push({[key]: pair[1]})
}

for(let pair of b.entries()) {
    const key = pair[0];
    arr2.push({[key]: pair[1]})
}

And then you can just compare two arrays of objects.

Comments

0

I ended up with this.

export default function formDataEqual(one, two) {
    return new URLSearchParams(one).toString() === new URLSearchParams(two).toString();
}


It's not gonna count order of fields, but it seems to be way less complicated :)

1 Comment

best way I have found so far is to use the defaultValue and value in the element itself. developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement
0
 it('should generate form data', async () => {

                        const buffer1 = res.getBuffer().toString().replaceAll(res.getBoundary(), '')
                        const buffer2 = formData.getBuffer().toString().replaceAll(formData.getBoundary(), '')
                        expect(buffer1).to.be.equal(buffer2)
                    })

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.