Endpoint for Salesforce custom SOAP web service

It was surprising difficult to figure out what the endpoint should be for a custom SOAP web service created on Salesforce, probably due to the generic terms used.

When you create a custom soap web service in Salesforce, e.g.

and you want to figure out that URL to call it, you need simply do the following.

  1. Go to your class in Salesforce, Setup => Develop => Apex Classes => WebserviceExample (in my sample)
  2. Click the “Generate WSDL” button
  3. Look toward the bottom for the service element, and find the port’s soap:address element, and there it is! As of v32.0 it’s of the format: https://{node}.salesforce.com/services/Soap/class/{classname}

Here’s the portion of the WSDL you should find:

If you attempt to call your custom web service methods using the Partner WSDL, Enterprise WSDL, Apex, Metadata, etc. etc. you will presented with this error:

No operation available for request …

Tagged , , , | Comments Off

Using jquery selectors with dynamic visualforce

JQuery is a great js library, you can easily grab a component or list of components using any number of selectors.

Using it with visualforce can present a problem, however. When you specify an id attribute on a VF component, it outputs in a hierarchical colon separated value, for example:

<apex:page id="thePage">
  <apex:form id="theForm">
    <apex:outputPanel id="thePanel" />
  </apex:form>
</apex:page>

It will generate something of the following format for the innermost component:

<span id="thePage:theForm:thePanel" />

In order to reference this selector in JQuery, ideally you’d do the following:

$("#thePage:theForm:thePanel")

Unfortunately “:” is a special character in JQuery selectors, and will result in the following error:

Uncaught Syntax error, unrecognized expression: Syntax error, unrecognized expression: theForm

There are a number of ways to get around this.

  1. The simplest way is to provide a unique styleClass on the element, e.g.

        <apex:outputPanel id="thePanel" styleClass="thePanel" />
    

    which will generate

        <span id="thePage:theForm:thePanel" class="thePanel" />
    

    and at this point you can access it like this:

    $(".thePanel")
    

    Not a perfect solution, because classes really shouldn’t be forced to be unique, but it works.

  2. If you’re not accessing the id dynamically, you can double-blackslash escape the “:”, e.g.
    $("#thePage\\:theForm\\:thePanel")
    

    Kind of a pain, and ugly, but it works. If you are accessing the id dynamically with the $Component variable, e.g.

    {!$Component.thePage.theForm.thePanel}
    

    obviously you cannot double-blackslash escape without doing some javascript string replacement, but that’s even uglier.

  3. The easiest and seemingly best solution is to just pass the results of document.getElementById to the $() method, which can take an HTML object as a parameter, e.g.
    $(document.getElementById("thePage:theForm:thePanel"))
    

    or

    $(document.getElementById("{!$Component.thePage.theForm.thePanel}"))
    
  4. Seems to work in every scenario.

Tagged , | Comments Off

SOQL/SOSL: Using NOT LIKE

I’ve had to struggle to remember how to do this enough times that I think it’s worth documenting.

Using the LIKE keyword to filter records in a SOQL or SOSL query is a great way to do searching using a partial string match. Here’s an example:

  select Id, Name
  from Account
  where BillingState = 'WA'
    and Name like '%ray%'

But to exclude using the LIKE operator is a little more counter intuitive. Here’s the correct way to do it:

Good

  select Id, Name
  from Account
  where BillingState = 'WA'
    and (not Name like '%ray%')

Note that if you do any similar variants which you think might work, they will fail with the following error:

MALFORMED_QUERY … unexpected token: ‘not’

or

MALFORMED_QUERY … unexpected token: ‘like’

Here are some ways which you’d think might work, but do not.

Bad

  select Id, Name
  from Account
  where BillingState = 'WA'
    and not Name like '%ray%'

Bad

  select Id, Name
  from Account
  where BillingState = 'WA'
    and not (Name like '%ray%')

Bad

  select Id, Name
  from Account
  where BillingState = 'WA'
    and Name not like '%ray%'
Tagged , , | Comments Off

Apex Pattern: Save and Open PDF from button

I’ve heard variations to this request a few times now:

Can we have a button on the {object} where we generate a PDF, save it as an attachment on the {object} record, and open it?

Saving a PDF is so simple with Visualforce it’s ridiculous, simply utilize <apex:page> with the attribute renderAs=”pdf”. In fact, this is one of the early things that made me fall in love with the platform.

Here’s a simple pattern / template I built recently for being able to generate a PDF, save it, and open it all with one button click. This doesn’t contain any specific business logic or content in the PDF, feel free to use this and customize it to your heart’s desire! It could use some error checking and better tests before it’s production ready.

Here’s a demo of it in action:

Unable to display content. Adobe Flash is required.

Here’s the code:

Cheers!

Tagged , , , | Comments Off

Salesforce URL Hacking basics with retURL, saveURL and cancelURL

I have a rather large post about URL Hacking on Salesforce, but it occurs to me that some basics aren’t really addressed. Let’s address one of the fundamental components of URL hacking: navigation.

What happens to the URL when you edit a record in Salesforce using the standard edit button from the record detail page? It looks like this:

https://na10.salesforce.com/a0CA0000007RT6g/e?retURL=%2Fa0CA0000007RT6g

If we understand what every component of that URL is, we can “URL hack” it and modify the standard behavior so that we can customize navigation in our Salesforce application.

Let’s break the URL down from above:

  1. https://na10.salesforce.com/ — the domain
  2. a0CA0000007RT6g — the record we’re editing
  3. /e — the action for the record, e stands for edit in this case
  4. ? … — everything after the ? is the query string, which begins with a ? and is & delimited with key = value pairs, e.g. ?a=b&c=d&e=f, we have 3 variables being set: a which is set to b, c which is set to d and e which is set to f

Specifically above, the application is saying by default that we are editing the record a0CA0000007RT6g, and we want to the application to know that the retURL is set to %2Fa0CA0000007RT6g. %2F is url encoded (from a button or formula field we can use URLENCODE()), and once it’s decoded it becomes a forward slash, /. So once the URL is loaded, it knows that the retURL value is /a0CA0000007RT6g, which is the record we’re editing.

Let’s look at another example, open a Contact then click Edit next to a record on a related list. The URL that is loaded when I open the contact is

https://na10.salesforce.com/003F000001BPE2W

And the URL that is loaded when I click the edit link from the related list is

https://na10.salesforce.com/a0lF0000002Z86T/e?retURL=%2F003F000001BPE2W

a0lF0000002Z86T corresponds to the related record that I’m editing, and the retURL brings us back to the contact upon completion of editing.

What if we don’t want to go back to the Contact when we’re done, but instead stay on the order? It’s a simple URL hack to accomplish this non-standard behavior:

https://na10.salesforce.com/a0lF0000002Z86T/e?retURL=%2Fa0lF0000002Z86T

Now that we know how the URL is composed, we can predictably mold it to do what we want. retURL is a powerful URL parameter, and understanding how it works is fundamental to URL hacking.

There are other important URL parameters to keep in mind. What should we do if we want to redirect the user to a different place if they cancel the changes than if they save the changes? We can simply use saveURL and cancelURL for this purpose, or we can use them all three in conjunction.

The logic behind where the user is redirected on click of the Save button is as follows*:

  1. Is there a saveURL URL parameter set? If so, redirect to that.
  2. Is there a retURL URL parameter set? If so, redirect to that.
  3. Redirect to /home/home.jsp

*The behavior is slightly different if we’re creating a new record.

Similarly the navigation on the Cancel button follows:

  1. Is there a cancelURL URL parameter set? If so, redirect to that.
  2. Is there a retURL URL parameter set? If so, redirect to that.
  3. Redirect to /home/home.jsp

So if we want to specify a different location for the user to go on Cancel than on Save, we could simply supply a cancelURL and retURL. For example:

https://na10.salesforce.com/a0lF0000002Z86T/e?cancelURL=%2Fa0lF0000002Z86T&retURL=%2F003F000001BPE2W

This would bring us to the related record if we canceled, and bring us back to the Contact if we saved.

There are many other URL parameters used by Salesforce, but retURL, saveURL and cancelURL are the most fundamental.

In conclusion (tl;dr): we can use these fundamentals of url hacking for navigation to construct custom buttons and links to answer the question “can we forward the user somewhere else?” The answer: yes, absolutely.

Tagged , | Comments Off

Node.js http getaddrinfo ENOTFOUND

I had this code snippet (slightly modified from how to make external http requests with node.js):

var http = require('http');

var options = {
  host: 'http://api.untappd.com/',
  port: 80,
  path: '/v4/user/info/rdehler?...'
};

http.get(options, function(resp){
  resp.on('data', function(chunk){
    //do something with chunk
  });
}).on("error", function(e){
  console.log("Got error: " + e.message);
});

and I was given this error:

Express server listening on port 3000

events.js:72
throw er; // Unhandled ‘error’ event
^
Error: getaddrinfo ENOTFOUND
at errnoException (dns.js:37:11)
at Object.onanswer [as oncomplete] (dns.js:124:16)

Pretty dumb, the error explains the issue pretty clearly. ‘http://api.untappd.com/’ is not a valid hostname to pass into options.host, whereas ‘api.untappd.com’ is a valid hostname. Duh moment of the day.

Tagged | 1 Comment