Try ERPNext Buy Support Partners Foundation

Frappe.db.get_value returns a monolith of objects!

Hello community, I am once again, asking for your help.
So I want to fetch a few fields from the database using frappe.db.get_value. Seems simple enough.
This is my whole code:

frappe.ui.form.on('Repairs', {
        customer: function(frm) {
                var filters = cur_frm.doc.customer;
                var customer_info = frappe.db.get_value('Customer', filters, ['address_line1', 'customer_type']);                       
                    if (customer_info.customer_type === "individual") {
                            cur_frm.set_value("address", customer_info.address_line1)
                    };
            }
    });

Now the issue with this is, instead of the expected values, I get tons of different stuff I can’t work with.
Console.log(customer_info) results in this:

I tried unstructuring this whole thing but somethings seemms very wrong. I don’t need the whole query, just the results… Where did I go wrong?

explain the use case,

  var d = locals[cdt][cdn];
frappe.call({
      method: 'frappe.client.get_value',
      args: {
        doctype: 'Task',
        filters: {
          'project': d.project,
          'opportunity': d.opportunity,
          'subject': 'Proposal Drawing',
        },
        fieldname: ['name','status']
      },
      callback: function (data) {
        if (data.message.status == 'Open' || data.message.status == 'Overdue')
        frappe.db.set_value('Task', data.message.name, 'status', 'Cancelled');

      }
    });

i am using this for cancel pre-script-created Task if the Opportunity is cancelled

opportunity 

is custom field (Not in Task normally), i hope it will help.

    frappe.ui.form.on('Repairs', {
  customer: function(frm) {
    frappe.call({
      method: 'frappe.client.get_value',
      args: {
        doctype: 'Customer',
        filters: {
          'customer_name': cur_frm.doc.customer,
        },
        fieldname: ['adress_line1','customer_type']
      },
      callback: function (data) {
        if (data.message.customer_type == 'individual'){
          frm.set_value('address', data.message.address_line1)
          frm.refresh_field('address');
        }
      }    
    });
  }
});

should be something like this and don’t forget to refresh target field if you fetch field from another form.

The idea of this code is everytime the customer field is modified, it fills certain information (street in this case) into the address field, but only if it’s an individual customer, not a company.

@emre: This is more than I asked for! But I’ll try this out and see how it works. Thank you.
Although I would like to know why frappe.client.get_value has to be called by another function (frappe.call) rather than being able to be executed itself.

I am not expert on Frappe framework but as i see on example codes and github code investigation i used like this and its worked (if its work don’t touch :slight_smile: ).

1 Like

client.get is a server side func, frappe.call is a client side func which is used to call server side func from client scripts.

2 Likes

You said you found this on their github? Guess I need to take a look aswell because data.message is not defined. I don’t see why it needs to be there but if it does then I assume it’s some kind of frappe standard. Thank you.

Also @neerjavkn that makes a lot of sense now and I think it answers the initial question I had.

var d = locals[cdt][cdn];
  frappe.run_serially([
    () => frappe.call({
      method: 'frappe.client.get_value',
      args: {
        doctype: 'Task',
        filters: {
          'project': d.project,
          'opportunity': d.name,
          'subject': 'Survey',
        },
        fieldname: ['name','status']
      },
      callback: function (data) {
        if (data.message.status == 'Open' || data.message.status == 'Overdue')
        frappe.db.set_value('Task', data.message.name, 'status', 'Cancelled');
      }
    }),

i just rewrite for your situation. my script is running normally. could you check if filter its return any value?

A big thanks to everyone who helped with this. I chatted with @emre in private a little and we came to the result that the code has to look like this, for anyone interested:

 frappe.ui.form.on('Repairs', {
  customer: function(frm) {
    frappe.call({
      method: 'frappe.client.get_value',
      args: {
        doctype: 'Customer',
        filters: {
          'name': cur_frm.doc.customer,                                                                                                                                                                                                              },
        fieldname: ['address_line1']
      },
      callback: function (data) {
        frm.set_value('address', data.message.address_line1);
        frm.refresh_field('address');
      }
    });
  }
});

Now I haven’t set the individual condition yet, but from here on, it should be easy.