How to handle empty form field to send to API?

My case is I have custom button in a form which take values from fields and using frappe.call send it to server side which then send it to a REST POST request to create a document on other site.

The problem is there are empty field in the form. And the frappe.call seems not sending the empty key:value to the server side, hence generating fail in the requests.

If I fill-in or don’t include the empty fields, the script run sucessfully and post a document.

How should I properly handle this empty fields?

Set default values on the server side?

There is no default values. The value should be the same as in the form (collected by the button).
Now I use this to temporary assisgn value to the frappe.call fieldname args.

if (d.field1 == null || "" ) {var d.field1 = " "} else {var d.field1 = d.field1}

This isn’t what I meant.

Set default values on the server side function, that is, the python function.

I did the default values but still failed:

def mymethod(doctype, name=None, fields=None):

and also tried

def mymethod(doctype, name=None, fields={}):

and still fails.

In the article, the examples saying the dict is empty. In my case the value for a key is empty. And this key is not passed to py. Hence the failure.
If I exclude the empty fields, the passing and requests are successful.

A simple if condition would fix that then.

if key not in dict:
    dict[key] = default-value

How is this if condition work?
There are keys that are not passed from js to py so py doesn’t know if the keys exist.
For example in the args of frappe.call

"fields": {
    "field1": d.field1,
    "field2": d.field2,
    "field3": d.field3
}

in the form, the field2 is empty. Then the frappe.call will pass

{"field1": "value1", "field3": "value3"}

so the if condition will be

if field2 not in dict:
    dict[field2] = ""

And this is made for every (non mandatory) field in the form?
Is that so?

I do this in the js for the if condition

Either that, or you can directly modify the args dictionary in frappe.call.

args = {
    parameter_1 = d.field1 || " "
}

Altho, I believe handling it in the server side is better.

It works with this I think. It seems not consistent… I don’t know if it is my browser cache or else. Going to test it more.

Even if empty or null, frappe.call should pass the args no matter what. I’m unsure why it hasn’t passed in your case.

That’s what I thought too. Usually it’s enough to use fields=None.
Well thanks anyway… I hope I got my fixed solution :crossed_fingers:

What is the difference of:

d=locals[cdt][cdn]
#then in frappe.call:
field1 = d.field1

compared to:

field1 = frm.doc.field1

This is cache. The values are fetched from cache memory.

This is live data.

This is my understanding. Feel free to correct if it’s wrong.

Hi @rahy,

In my experience there are 2 scenarios to tackle in this context, 1. Empty field, 2. Field really exists or not. The 2nd problem can be solved easily by looping through the keys but 1st problem is different which is where you are stuck with.

As for the solutions, i have use this package validator · PyPI in a while now. It is much easier to handle complex validation scenario and easier to understand.

May be you can try it out too, i hope this help. Thanks.

Thank you @mrjurin,
I will take a look at it and try it.