Update Nova resource with a empty string as default for field - laravel-nova

I have an existing data model that has a unique indexed string field that defaults to an empty string.
I added an $attributes property to the model to default it to an empty string when creating a new object. That works just fine.
However when updating the object and the field remains empty, it will fail since the field is returned as null and the DB field is not nullable. I am not sure of the impact of making that field nullable(). Too much code to dig through so I can't change it.
I am thinking I can observe for an event, and change the value from null to empty string there, but I would rather take care of this in Nova.
Is there anyway to tell Nova an empty field should be saved as an empty string?

Short version: no.
Long version:
This cannot be set in Nova. An empty string will be passed as null in the HTTP request. This behaviour is part of Laravel's core. The only way to make sure it isn't passed as an empty string from Nova is to put form validation on it and make it a required field.
If you don't mind changing code on the Laravel app level, you can disable this behaviour by removing the ConvertEmptyStringsToNull middleware in your app's Kernel.
/app/Http/Kernel.php
protected $middleware = [
...
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, // remove this line
];
However, if the DB field isn't nullable, the field has to have a value anyway right? I'd suggest putting an accessor on the model to check for null values:
public function setMyFieldAttribute($val)
{
$this->attributes['my_field'] = $val ?? '';
}
Or, if you want to be really certain it always has a value, add an observer for the saving event (as you already mentioned), and make sure the field has a value before the data is actually saved.

Related

Avro schema: adding a new field with default value - straight default value or a union with null?

So I have an avro record like so (call it v1):
record MyRecord {
array<string> keywords;
}
I'd like to add a field caseSensitive with a default value of false (call it v2). The first approach I have is:
record MyRecord {
array<string> keywords;
boolean caseSensitive = false;
}
According to schema evolution, this is both backward and forward compatible because a reader with the new schema v2 reading a record that was encoded with old writer schema v1 will be able to fill this field with the default value and a reader with older schema v1 will be able to read a record encoded with the new writer schema v2 because it will just ignore the newly added field.
Another way to add this field is by adding a union type of null and boolean with a default value of null, like so:
record MyRecord {
array<string> keywords;
union{null, boolean} caseSensitive = null;
}
This is also backward and forward compatible. I can see that sometimes one would want to use the 2nd approach if there is no clear default value for a field (such as name, address, etc.). But given my use case with a clear default value, I'm thinking of going with the first solution. My question is: is there any other concerns that I'm missing here?
There will be a potential issue with writers in the first case--apparently writers do not use default values. So a writer writing "old data" (missing the new field--so writer is publishing a record with the "keywords" field only) will blow up against the first schema. Same writer using second schema will be successful, and the "caseSensitive" field will be set to null in the resulting message.

How to update value in angular ui typeahead directive if no matching option is found

I've an array of objects containing title and salary which is used in typeahead directive.
I display department name and get entire object as value.
If none of the options match, I want user entered string to be converted to object still. Is there any way to update that?
This answer is pretty late, but I would just use ng-blur (to trap the end of the users input) along with a variable bound to typeahead-no-results. Then test if the variable is true in the method bound to ng-blur, and, if so, make an object out of the String supplied by the user and push it to your data source. Simple example found here.

Scout Eclipse Neon set title of the field label in form data

I am wondering if you could set title of field in form data on server side.
Use case for this is that you have one field, and depend on some server logic you would set title of the field. Is it posible to set it on server somehow, to not sending string value to client and then set the title.
I was looking at method
formData.getMyField.setPropertyByClass(c, v);
but I don't know if this method could do this and which property I need to set.
FormData classes can contain two types of data holder classes:
data holders for values associated with value fields (these holders always extend AbstractValueFieldData) and
data holders for values associated with form data properties (these holders always extend AbstractPropertyData).
A form data property is generated if the associated form has a member variable whose setter and getter is annotated with #FormData.
The method setPropertyByClass(...) is intended to set the value of a form data property in a form data object.
The method cannot be used to set the label of a form.
The standard way to set the label of a field would be to load the form data from the server and to set the label afterwards, as in the following code snippet:
...
public class ModifyHandler extends AbstractFormHandler {
MyFormData formData = SERVICES.getService(IMyProcessService.class).load();
importFormData(formData);
getMyField.setLabel(formData.getMyProperty().getValue());
}
...

BreezeManager doesn't track changes with extended properties

I extended my server entity with some properties in the client side .
When getting data from the query I really see these properties in the result filled with the proper values .
When I change a value of an extended properties the manager doesn't track this change .
When I call manager.rejectChanges() no action is happen , I debugged the code and I see in the entityAspect.entityState ("Unchaged") although I modified the property.
If I modify a property comes from the server entity every thing is ok.
Here is my Product entity in the server :
public class Product
{
public string Code {get;set;}
}
I extended the product in the client side with some others :
var Product = function () {
this.kind = ko.observable();
};
breeze.metadataStore.registerEntityTypeCtor("Product", Product);
After the query I get both field (Code , Kind) , if I change Code , entity state is modified , I can call manager.rejectChanges and its takes effect, but if I change kind nothing happen , the entity state is "Unchaged".
Any idea why this happen ?
Thanks in advance ...
By "extended" I assume you mean "unmapped" properties which are typically defined in a custom constructor as described in "Extending Entities"
"Unmapped" properties do not map to permanently stored values on the server. Therefore, changes to unmapped properties do not affect EntityState and they are not sent to the server.
Note that the server can supply the value of an unmapped property in the payload of a query and Breeze will set the unmapped property accordingly. This is a way to calculate non-persisted values on the server and transmit them to the entity on the client.
On the client an unmapped property behaves in other respects like a mapped property:
conforms to the syntax of the model library (e.g., it becomes an observable in KO models)
serialized when exported
validation rules apply
raises propertyChange when the value is changed
entity remembers the property's "original value"
rejectChanges() reverts the property to that original value

Passing value to database

does an empty text box pass an empty value to the database ** SQL server 2008** or an empty
string
i am using string.empty method before saving the data cause i need to clear the data
before the user inputs anything
i am not allowing nulls in my table but the passed value by the text box seems to be passed
as " " not as null so the table is accepting that value and I don't want that to happen
You could set the textbox value to null instead op String.Empty
It's also recommended to check the input before adding it to the database. Like so:
if (String.IsNullOrEmpty(txtTextbox.Text))
//No value

Resources