Get modified doc from backend is reloaded on frappe.set_route()

Looking for some insights from fellow frappe developpers.

Let me try to explain my scenario with this simplified example.

In doctype_a form, I have a button “make_doctype_b”.

Button’s click handler calls backend method:

frappe.call({
	method: "...make_doctypeb",
	args: {
		doctype_a_name: frm.doc.name
	},
	callback: async function(r) {
		frappe.model.sync(r.message);
		frappe.get_doc(r.message.doctype,r.message.name).__run_link_triggers = true;
		frappe.set_route('Form', r.message.doctype, r.message.name);
		
	}
});

The backend method make_doctype_b:

frappe.whithelist()
def make_doctype_b(doctype_a_name)
	if can_find_existing():
		doc = frappe.get_doc(...)
	else:
		doc = frappe.new_doc()
		
	doc.link_to_doctype_a = doctype_a_name
	return doc

So basically the backend methods tries to find an existing doc, if not it creates a new one. And it assigns a link field to doctype_a.

In the callback javascript, we sync the doctype_b model and we redirect to doctype_b.

This is working fine when backend returns a new doc.

The issue I am having is when the backend returns an existing record.
Even though I used frappe.model.sync(), the frappe.set_route() still trigger a reload from server and I loose to modified value set in link_to_doctype_a property.

What I would like is the user to be redirected to the modified doc, showing Unsaved state and having the Save button readily available.

How to tell frappe to not reload the doc I just returned and keep its modified state ?

Thanks!

Anyone?

Hi @guimorin,

Just try it.

Here, added only is_new in the callback, if is_new is true, the document will be redirected as before. However, if is_new is false, the document will be redirected without reloading, preserving its modified state.

callback: async function(r) {
    frappe.model.sync(r.message.doc);
    frappe.get_doc(r.message.doc.doctype, r.message.doc.name).__run_link_triggers = true;

    if (r.message.is_new) {
        frappe.set_route('Form', r.message.doc.doctype, r.message.doc.name);
    } else {
        // Preserve modified state and redirect without reloading
        frappe.set_route('Form', r.message.doc.doctype, r.message.doc.name, { 'skip_saving': 1 });
    }
}
@frappe.whitelist()
def make_doctype_b(doctype_a_name):
    if can_find_existing():
        doc = frappe.get_doc(...)
        is_new = False
    else:
        doc = frappe.new_doc(...)
        is_new = True

    doc.link_to_doctype_a = doctype_a_name
    doc.save()

    return {
        "doc": doc.as_dict(),
        "is_new": is_new
    }

Check and modify your code according.

Thank You!