Core Data check if property has never been set - core-data

Is there a way to check if a NSManagedObject property, for example a float NSNumber, which has a default value = 0, has already been set in the setter?
I tried something like this:
-(void)setQuantity:(NSNumber *)quantity {
if (self.quantity==nil)
NSLog(#"Property never been set");
else
NSLog(#"Property already set");
[self willChangeValueForKey:#"quantity"];
[self setPrimitiveQuantity: quantity];
[self didChangeValueForKey:#"quantita"];
}
But "quantity" is never nil because initialized with default value. Thanks!

If the attribute has a default value it has been set during initialization. You have 2 options:
Mark the attribute as optional and don't provide a default value. You can check for nil.
Make sure the default value is unique and check against that value to determine if it has been changed since initialization. E.g., for otherwise positive numbers, use -1.
Caveat for 1.: make sure nowhere in your code the attribute is set to nil again.
Caveat for 2.: make sure nowhere in your code the attribute is set to the unique value.

Related

Checking for Null Values in CRM 2011 Custom Workflow Activity

I am trying to perform some logic in a CRM 2011 Custom Workflow Activity with some attributes from the calling entity. I am having an issue with determining whether a particular attribute is null or not. I have tried seemingly all combinations of GetAttributeValue and the Attributes collection, but it seems that I will always get either a Specified Cast is not Valid or Object Reference Not Set to an Instance of an Object error when there is a null value for an attribute I'm trying to access. Does anyone know the correct method for accessing an attribute that may be null? In this example, I am working with attributes of the Guid/Entity Reference type.
You can always check to see if the attributes collection contains the specific attribute that you're looking for, but you shouldn't even have to do that. All Non-nullable types (Guid, DateTime, etc) are stored as nullable types in the Attributes collection and that's probably your problem. Try something like this ( assuming late bound):
var isValid = entity.GetAttributeValue<bool?>("new_IsValid");
CRM never returns a non-nullable value. Even things that you think would be null (bool, DateTime, int, etc) are returned as their nullable equivalent. A non-nullable cast will still succeed if the value is not null, but if the value is null, it'll give you a null reference error;
object a = new bool?(true);
bool value = ((bool)a); // Works
object b = new bool?();
bool value = ((bool)b); // Null Ref Error
This syntax ended up working for me:
//if current outside counsel not null, grab GUID value
if (thisCase.lgl_outsidecounselid != null)
{
currentOCGUID = thisCase.lgl_outsidecounselid.Id;
}
//it's null, set Guid to Guid.empty
else
{
currentOCGUID = Guid.Empty;
}

UltraNumericEditor allows values larger than MaxValue setting

Using infragistics UltraNumericEditor, if I set the .MaxValue to 50, the control will allow me to enter decimals larger than the limit (for example, 50.99)
I see the same behavior if I set the .MaxValue property to 50.01 (can set values larger)
I can obviously resolve this in code but resetting the value, but it seems like the control should do this on its own.
Is there something I'm missing in how to use these properties correctly?
I suppose you are using the UltraNumericEditor with the property Style set to Decimal (or Double).
In this case the control allows you to insert digits that render the input invalid with respect to the property MaxValue. However, by default, you are not able to exit the control until the value is correct.
If you want, you can use the event ValidationError that gives your the ValidationErrorEventArgs parameter. This parameter contains the LastValidValue property to reset the wrong value, the RetainFocus to let your user exit from the editor (or, if you prefer, display an error message)
private void ultraNumericEditor1_ValidationError(object sender, ValidationErrorEventArgs e)
{
// Reset the content to the last valid value and allow the exit from the editor
ultraNumericEditor1.Value = e.LastValidValue;
e.RetainFocus = false;
// In alternative display a message, but leave the wrong value to be reedited
// DisplayValidationMessage("The max value allowed is 50.00");
}
The problem was a result of the IEditorDataFilter for percentage values.
Infragistics recommends, and I had implemented, an IEditorDataFilter which converts decimal percentages (.5 = 50%) into percentages for display.
This filter is applied before the validation for the control takes place. Therefore, setting the MaxValue to "50" allowed me to enter "50.99" but not "51"... normally this would have caused a validation error as per Steve's answer. However, because of the IEditorDataFilter applied to this control, the value was automatically converted to .5099 and this new value does not violate the constraint.
The solution I implemented was to check the value in the Validated event to see if it was larger than the MaxValue / 100, and if so to set it equal to the same.

getSubmittedValue() vs. getValue()

Is that correct:
When I query a value before validation (or if validation failed) I have to use getSubmittedValue();. Once the value is validated, even if I query it in another validation later in the page/control I have to use .getValue(); since getSubmittedValue(); returns null after successful validation?
This xsnippet makes it easier to handle this. It allows you to just call getComponentValue("inputText1") to get either value or submittedValue.
Here's the function for reference:
function getComponentValue(id){
  var field = getComponent(id);
  var value = field.getSubmittedValue();
  if( null == value ){
         // else not yet submitted
         value = field.getValue();
  }
 
  return value
}
There's a slightly easier way: if you're just expecting a simple single-value String, just call:
var compare = firstField.getValueAsString();
Otherwise, call:
var compare = com.ibm.xsp.util.FacesUtil.convertValue(facesContext, firstField);
The former calls the latter anyway, but is obviously a terser syntax. This does what you're looking for and more:
If the value hasn't yet been validated, returns the submitted value
If validation has already passed, returns the value after it's already been processed by any converters and / or content filters, so particularly in cases where you're trying to compare two field values, this should ensure that both values have been properly trimmed, etc., and is therefore less likely to return a false positive than just comparing the raw submitted values.
Found the answer here. So when you want to ensure that 2 text fields have the same value (use case: please repeat your email) and the first box already has a validation that might fail, you need to use submittedValue unless it is null, then you use the value. Code in the validation expression for the second field looks like this:
var firstField = getComponent("inputText1");
var compare = firstField.getSubmittedValue() || firstField.getValue();
compare == value;
You have to love it.

NsMutableArray null value

I have a situation here. I have a UITableviewController with textfields in it in the cell. Each cellthas a textfield in it. The user enters the value in the textfields and i am saving the textfield data in to an NSMutableArray. But if the user doesnot enter a single field then my array gives the error
"CoreAnimation: ignoring exception: * -[NSMutableArray insertObject:atIndex:]: attempt to insert nil object at 2". NSmutableArray cannot have a null value. How will i handle this situation. Any help is appreciated.
Thanks
A couple of quick solutions: I'm assuming that you must have a value in the array at the index that corresponds to the row, so what to put in? Stuff an [NSNull null] object in there, or simply an empty string.
if (!txtField.text) // if the textfield's text is null
{
[myMutableArray addObject:[NSNull null]];
}
One issue about this is that when reading your array, you cannot assume that the array holds a string: you must check it for [NSNull null] before setting your text.
Another solution to the issue would be to simply create an NSMutableDictionary to hold the values you wish to store, the key would be the NSIndexPath and the value would be the value you are storing. If the value is null, don't store anything at all. This way you would have no need to store null values.

Core Data uniqueness

Is there any way I can validate a value updated in a Core Data entity's property against values of the property in other entities in the collection?
At the moment I create an entity with some default values, add it to arrangedObjects, then get the user to modify the various property values. However, I would like to check a particular property and make sure there're no other entities in the array with the same value for that property. What's the best way to do this?
Many thanks,
Dany.
Manually checking is only a few lines of code with a fast enumeration loop:
BOOL unique = YES;
for (NSManagedObject *obj in collection) {
if (obj.property == value) {
unique = NO;
break;
}
}

Resources