I have a template that is looping through a GroupedList of data from an API (that I don't control) in a template. This has worked fine for a while, but now some of the elements in the loop are Null, instead of an array of data, resulting in an error. If I check the fields themselves for Null. I get the same error.
Uncaught TypeError: method_exists(): Argument #1 ($object_or_class) must be of type object|string, null given
<% loop $indices %>
<% if fileName %>
$fileName
<% end_if %>
<% end_loop %>
This error has cropped up since upgrading to php8 from 7.4 and running a composer update.
How can I check the loop item has data and is not Null?
You might not control the API, but the $indices variable will be in some PHP you control, yes? I.e. you have some PHP code which gets data from the API and then passes it to the template.
I would recommend removing null values before passing to the template.
I am pretty sure there's no way to check if the current scope object is null in Silverstripe's templating language.
UPDATE: I think this PR will stop this scenario from triggering an exception: https://github.com/silverstripe/silverstripe-framework/pull/10589
Related
With Silverstripe templates, can I pass a variable from one include to another?
Within Order_ConfirmationEmail.ss <% include Order SendingEmail=true %>. Set $SendingEmail to true.
And in Order.ss pass $SendingEmail to another template via another include:
<% include Order_Content SendingEmail=$SendingEmail %>
Then use the variable $SendingEmail in Order_Content.ss:
<% if $SendingEmail %>We are sending an email <% end_if %>
Unfortunately, $SendingEmail does not have a value in Order_Content.ss (it does in Order.ss). Is this approach possible? Is there a better way. Thanks in advance.
It should. I'm not sure of all the ins and outs unfortunately, but so far as I know that is a thing (being able to pass any variable in scope). But there are a number of caveats you should probably be aware of. The biggest one being scope. If you're changing context at any point (and you have multiple layers so this is somewhat likely) you need to ensure the variable you're attempting to reference is in scope. Otherwise it will be blank, and thus report as such on any further reference to it. This is the most common problem when it comes to templates, so it always pays to double (triple) check.
I have used PreviousPage property and it always worked fine passing data from one page to another. Recently, I tried to add error handling into my code using try...catch method saving the exception in a text file. Using this method, I am getting the following exception on a line like TitleResultlbl.Text = PreviousPage.TitleProp while the program runs fine as before.
Exception.message:
Object reference not set to an instance of an object.
Why do I get this exception?
I am using vb.net and all references in pages are correct. Your help will be appreciated.
If the code is called for the first page, there will be no previous page
If PreviousPage Is Nothing Then
TitleResultlbl.Text = ""
Else
TitleResultlbl.Text = PreviousPage.TitleProp
End If
I found the problem to be the postback issue on the second page. In fact, when I was clicking on a final approval button on the second page, its Page_Load sub was being called again and there wasn't any checking like "If Not IsPostBack" before the lines accessing values from the first page inside that sub. It caused the 'PreviousPage.TitleProp' to be run again where it couldn't find the PreviousPage anymore causing the exception! I added the above IF clause around the codes in Page_Load sub and it worked fine.
I wish to use the same form for adding and editing records within a database using a partial view. I understand that this is fine as the standard Html.BeginForm automatically output the correct html depending on the action that is being used (Add / Edit).
However, I need to out said form with some extra HTML attributes. There does not appear to be an overload that allows this to happen without also specifying the ACTION and CONTROLLER names.
If I hardcode these then surely I cant use the same form for edit and add automatically?
Or am I missing something?
CHeers
Set the values of the action and controller to null and they will be pulled from the context. If you look at the source for the overload that doesn't require parameters, you'll see that it simply calls the versions requiring more parameters with these values as null. Calling that overload directly with null values will have the same effect. Depending on the overload you're using you might need to cast the null values as strings -- I'd do this only if the compiler is not able to differentiate the methods without casting the nulls as strings.
<% using (Html.BeginForm( null, null, FormMethod.Post, new { #class = "foo" } ))
{ %>
<% } % >
I upgraded a MVC1 project to MVC2, now all my calls to RenderPartial are throwing
System.ArgumentNullException: Value cannot be null.
However this does works:
<% Html.RenderPartial("~/Views/Shared/LogOnUserControl.ascx"); %>
And this does not (works in MVC1):
<% Html.RenderPartial("LogOnUserControl"); %>
Did the behavior of RenderPartial change?
Bleh.... found the problem, my project was referencing MVCContrib 1.0, downloaded the latest build and referenced that instead fixed the issue.
Your call to
<% Html.RenderPartial("LogOnUserControl"); %>
seems to be working fine otherwise you would be receiving
The partial view 'LogOnUserControl' was not found. The following locations were searched....
Considering that
When Html.RenderPartial() is called with just the name of the partial view, ASP.NET MVC will pass to the partial view the same Model and ViewData dictionary objects used by the calling view template.
and
ArgumentNullException is thrown when a method is invoked and at least one of the passed arguments is a null.
It seems like the Authentication arguments are not being passed properly to LogOnUserControl or maybe you have customised it in someway?
If I have a control, within a FormView, that is bound using a <% #Bind(...)%> expression. At run time, is there any way of retrieving the name of the field the control is bound to.
To be clear, if the expression is <% #Bind("UserName") %>
I want to return the string "UserName".
after messing around extensively in debug, I found this to work
((System.Web.UI.WebControls.AutoGeneratedField)((System.Web.UI.WebControls.DataControlFieldCell)(e.Row.Cells[0])).ContainingField).SortExpression
In debug use shift+F9 to open the quick watch window pain and explore your Event Argument visually