Development discussions around Shopify APIs
Hi,
I managed to get a script to work to hide Expedited Shipping for PO Boxes and show Standard Shipping instead (It's the only time we show Standard Shipping).
We launched a week ago and since then, I got 8 production errors (with dozens of sales). It's always the same RuntimeError: undefined method 'upcase' for nil
Can anyone help me figure out what's going on? I really appreciate it!
Here's the script, the error happens on row 2 where I put the word in bold:
#Script begin
#Exclude Expedited option when PO Box is present
shippingaddress1 = Input.cart.shipping_address.address1.upcase.split[0...-1].join ' '
checkpobox = ['PO BOX','POBOX','P.O BOX','PO. BOX','P.O.BOX','P.O. BOX','P.0. BOX','P.OBOX']
puts shippingaddress1
#define hideship based on checkpobox. If so, hide shipping options, otherwise allow all
if checkpobox.include?(shippingaddress1)
hideship = ['Expedited']
else
hideship = ['Standard']
end
#With hideship defined, now we loop through shipping rates to delete those that match
Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
hideship.any? { |hideship| shipping_rate.name.include?(hideship) }
end
#Script end
Solved! Go to the solution
This is an accepted solution.
Hey @Dominic_Nadeau
Try wrapping the code instead:
unless Input.cart.shipping_address.address1.nil? ...your code end
Scott | Developer Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Hey @Dominic_Nadeau
This will occur if address1 is blank.
Wrap your login in "if there's a shipping address1...", or use a Safe Navigation Operator.
Scott | Developer Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Ok, so what I understand is that it does not really affect the customer's experience since the error only triggers when a required field is blank (it can't be blank anyway to proceed to shipping). So, that's great, I'm worrying less.
Could you please elaborate on how to implement the IF within my code? I am not really knowledgeable on Ruby.
Thank you
Are you able to share the store URL? The scripts editor should shed some light on how these are coming through.
Scott | Developer Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Thanks @Dominic_Nadeau
it can't be blank anyway to proceed to shipping
I thought the same thing, so I just dug a little deeper. It turns out Google Pay can trigger Shipping Scripts without an address1. The timing seems to line up with the latest error that was generated + order #8643 (which used GPay).
To get around this, short-circuit the script:
return if cart.shipping_address.address1.nil?
...the rest of your script
Scott | Developer Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Apologies, typo:
return if Input.cart.shipping_address.address1.nil?
Be sure to test this before publishing.
Scott | Developer Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Hi Scotty,
Yesterday, I added the line to the script and tested it out without errors before publishing.
Today, though, I received 2 new RuntimeError for "unexpected return".
What does that mean?
It was followed by orders US#8679 and US#8680 both paid using Shopify Payment.
Thank you for you help
This is an accepted solution.
Hey @Dominic_Nadeau
Try wrapping the code instead:
unless Input.cart.shipping_address.address1.nil? ...your code end
Scott | Developer Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Hi again,
After applying the fixes mentioned above, I didn't get errors for a while.
Unfortunately, I now ran into a new RuntimeError:
undefined method 'map' for nil on line 7
Is this something you are familiar with?
Thanks
Hey @Dominic_Nadeau
Output.shipping_rates always need to be set. In this case it's only set when address1 has a value. A quick fix would be to replace the last end with:
else Output.shipping_rates = Input.shipping_rates end
Be sure to test the update before publishing 🙂
Scott | Developer Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Hi Scotty,
It seemed like the script was working fine for a while. We then received a few messages from customers trying to order from Hawaii that would not see any rate returned.
Deactivating the script enabled the "Standard Shipping" rate to be shown. Would you have any idea why this would happen and how to fix it?
Here's the complete script:
#Exclude Expedited option when PO Box is present
unless Input.cart.shipping_address.address1.nil?
shippingaddress1 = Input.cart.shipping_address.address1.upcase.split[0...-1].join ' '
checkpobox = ['PO BOX','POBOX','P.O BOX','PO. BOX','P.O.BOX','P.O. BOX','P.0. BOX','P.OBOX']
puts shippingaddress1
#define hideship based on checkpobox. If so, hide shipping options, otherwise allow all
if checkpobox.include?(shippingaddress1)
hideship = ['Expedited']
else
hideship = ['Standard Shipping']
end
#With hideship defined, now we loop through shipping rates to delete those that match
Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
hideship.any? { |hideship| shipping_rate.name.include?(hideship) }
end
else
Output.shipping_rates = Input.shipping_rates
end
Hey @Dominic_Nadeau
Scripts can't see shipping profiles but you could examine the shipping address instead. Maybe something like:
unless Input.cart.shipping_address.address1.nil? or Input.cart.shipping_address.province_code == 'HI'
...
Be sure to test this as a preview before publishing.
Scott | Developer Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Hey @SBD_,
Thanks for your answer.
If I understand correctly, the complete code should look like this:
#Exclude Expedited option when PO Box is present
unless Input.cart.shipping_address.address1.nil?
shippingaddress1 = Input.cart.shipping_address.address1.upcase.split[0...-1].join ' '
checkpobox = ['PO BOX','POBOX','P.O BOX','PO. BOX','P.O.BOX','P.O. BOX','P.0. BOX','P.OBOX']
puts shippingaddress1
#define hideship based on checkpobox. If so, hide shipping options, otherwise allow all
if checkpobox.include?(shippingaddress1)
hideship = ['Expedited']
else
unless Input.cart.shipping_address.province_code == 'HI'
hideship = ['Standard Shipping']
end
end
#With hideship defined, now we loop through shipping rates to delete those that match
Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
hideship.any? { |hideship| shipping_rate.name.include?(hideship) }
end
else
Output.shipping_rates = Input.shipping_rates
end
If I want to add province codes, should it look like 'HI, AK, AE' ?
I am also getting an "undefined method 'address1' for nil error on line 2 since before I added the new code...
I am going to test things out, but I feel like the error will get in the way.
Update*
Hey @SBD_,
I managed to get the script working again (Standard shipping is hidden except for Hawaii, ALaska and the Armed Forces).
One functionality I lost in the meantime is to hide Expedited shipping and show Standard Shipping when any version of the word PO Box is in the address1 field.
Could you please help me figure out what the issue could be? Complete code:
#Exclude Expedited option when PO Box is present
unless Input.cart.shipping_address.address1.nil? or Input.cart.shipping_address.province_code == 'HI' or Input.cart.shipping_address.province_code == 'AK' or Input.cart.shipping_address.province_code == 'AA' or Input.cart.shipping_address.province_code == 'AE' or Input.cart.shipping_address.province_code == 'AP'
shippingaddress1 = Input.cart.shipping_address.address1.upcase.split[0...-1].join ' '
checkpobox = ['PO BOX','POBOX','P.O BOX','PO. BOX','P.O.BOX','P.O. BOX','P.0. BOX','P.OBOX']
puts shippingaddress1
#define hideship based on checkpobox. If so, hide shipping options, otherwise allow all
if checkpobox.include?(shippingaddress1)
hideship = ['Expedited']
else
hideship = ['Standard Shipping']
end
#With hideship defined, now we loop through shipping rates to delete those that match
Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
hideship.any? { |hideship| shipping_rate.name.include?(hideship) }
end
else
Output.shipping_rates = Input.shipping_rates
end
Thanks for your help!
Hi Scotty,
One thing I forgot to mention: Hawaii is in a different shipping profile which does not return Expedited Shipping rates. I think that since there is no PO Box in the address, it applies the "Else" condition, hiding the Standard shipping rate. How can I only activate the script for one shipping profile?
Thank you
Photo by Marco Verch Sales channels on Shopify are various platforms where you can sell...
By Ollie May 25, 2023Summary of EventsBeginning in January of 2023, some merchants reported seeing a large amo...
By Trevor May 15, 2023With 2-Factor Authentication being required to use Shopify Payments, we’re here to help yo...
By Imogen Apr 26, 2023