Ember: are model initial values null or empty string? - ember.js

I am confused about the initialisation values of a new model.
When creating a new record, it seems that all properties have "null" as value.
As soon as you type something in the textfield (bound to the model), and then delete the typed value (thus again an empty textfield), the value of the properties becomes emptystring.
Is this the expected behaviour ?
There is a difference for REST API's whether they receive null or "" ...

if your atribute is DS.attr('string'), so this is correct.
Doesn't matter if the string is null or empty, this just represent that the text isn't present. Thinking in programming language you would be aware of the null, because you receive error when accessing methods. But in business rules, doesn't matter if the string is null or empty, so this is a common pattern, for example:
if (name == null || name.length == 0) {
// name is missing, prompt the user ...
}
And this is a rare situation:
if (name == null) {
// some logic here
} else if(name == "") {
// other logic here
}
About the record creating. When you create it, the values is null. But when binding to a text field, for example:
{{input type="text" valueBinding="field"}}
You have this relationship:
model.field <-> textfield.value
When you set something in model.field, it will be syncronized with the textfield and vice-versa. But in the case of editing the textfield, the value will always be a string, this is the reason that you receive a empty string, instead of null, when clearing the textfield.

Related

Ember.js: How to get an array of model IDs from a corresponding array of model attributes

For a Tag model that I have in Ember-Data, I have 4 records in my store:
Tags:
id tag_name
1 Writing
2 Reading-Comprehension
3 Biology
4 Chemistry
In my code I have an array of tag_names, and I want to get a corresponding array of tag IDs. I'm having 2 problems:
My server is being queried even though I have these tags in my store. When I call store.find('tag', {tag_name: tag_name}), I didn't expect to need a call to the server. Here is all the code I'm using to attempt to create an array of IDs.
var self = this;
var tagsArray = ["Writing", "Reading-Comprehension", "Chemistry"];
var tagIdArr = []
tagsArray.forEach(function(tag_name) {
return self.store.find('tag', { tag_name: tag_name }).then(function(tag) {
tagIdArr.pushObject(tag.get('content').get('0').get('id'));
})
})
return tagIdArr;
When I console.log the output of the above code gives me an empty array object with length 0. Clicking on the caret next to the empty array shows three key-value pairs with the correct data. But the array is empty. I'm sure there is a simple explanation for this behavior, but I'm not sure why this is. I've used code similar to the above in other places successfully.
Find hits the server, but peek does not.
var tagsArray = ["Writing", "Reading-Comprehension", "Chemistry"];
return this.store.peekAll('tag').filter(function(tag){
return tagsArray.indexOf(tag) !== -1;
}).mapBy('id');
See: http://emberjs.com/blog/2015/06/18/ember-data-1-13-released.html#toc_reorganized-find-methods

Why doesn't my Ember computed property get a second argument?

I expected a second argument to be passed to my computed property method, but it's not. I need this so I can call a setter to save my model with new data. Instead of that behavior, it appears that my computed property is called again right before I save the model, and clobbering the new values - the setter is never called at all because I only get one argument. Computed property:
changeBananas: function(k, v) {
var bananas = this.get('bananas'), bananaList = [];
console.log('args: ');
console.log(arguments);
bananaList = bananas.map(function(b) {
return { color: b.get('color') };
});
if (arguments.length > 1) {
console.log('I never get called!');
return bananaList;
}
return bananaList;
}.property('bananas.#each')
Full JSBin:
http://jsbin.com/razimaxu/2/edit
I tried propertyWillChange() and friends to try to stop observers, but it did not do anything. Is there another way to do this? My computed property is there to do some formatting of the items before displaying them in editable fields. I expected to be able to change said fields and save just like any other fields that are connected to regular model properties.
The only time it will receive both arguments is if you attempt to set the computed property, such as this.set('changeBananas', []).
It doesn't get called with both arguments if it has noticed a dependent property has changed.

If statement for cookie - WebMatrix/Razor

I have set a cookie that I want to use to populate a form, so that users don't need to keep filling out the same form (it's submitting an inquiry to owners of holiday villas).
I've got it working fine if the cookie is already set, but it errors out if there is no cookie set.
I'm guessing I'll need to use an "if" statement, but don't quite know how to write the code.
Here is the code that sets the cookie...
Response.Cookies["BookingEnquiry"]["ReqName"] = Request["BookingReqName"];
Response.Cookies["BookingEnquiry"]["ReqEmail"] = Request["BookingReqEmail"];
Response.Cookies["BookingEnquiry"]["ReqPhone"] = Request["BookingReqPhone"];
Response.Cookies["BookingEnquiry"]["NumAdults"] = Request["BookingNumAdults"];
Response.Cookies["BookingEnquiry"]["NumChildren"] = Request["BookingNumChildren"];
Response.Cookies["BookingEnquiry"]["ReqMessage"] = Request["BookingReqMessage"];
Response.Cookies["BookingEnquiry"].Expires = DateTime.Now.AddHours(4);
}
Here are the variables that collect info from the cookie...
var reqname = Request.Cookies["BookingEnquiry"]["ReqName"];
var reqemail = Request.Cookies["BookingEnquiry"]["ReqEmail"];
var reqphone = Request.Cookies["BookingEnquiry"]["ReqPhone"];
var numadults = Request.Cookies["BookingEnquiry"]["NumAdults"];
var numchildren = Request.Cookies["BookingEnquiry"]["NumChildren"];
var reqmessage = Request.Cookies["BookingEnquiry"]["ReqMessage"];
and here is a sample input from the form...
<label>Name</label>
<input type="text" name="BookingReqName" id="BookingReqName" placeholder="full nameā€¦" value="#reqname">
In WebMatrix C#.net, I think you are looking for something like this:
if(Request["BookingReqName"] != null)
{
Response.Cookies["BookingEnquiry"]["ReqName"] = Request["BookingReqName"];
}
else
{
Response.Cookies["BookingReqName"] = ""; //<--Whatever default value you want (I've used an empty string here, so you, at least, won't get a null reference error).
}
Or you can use the same code as a one liner (to not clutter up your code, however this will decrease readability, obv.).
if(Request["BookingReqName"] != null){Response.Cookies["BookingEnquiry"]["ReqName"] = Request["BookingReqName"];}else{Response.Cookies["BookingReqName"] = ""; //<--Whatever default value you want (I've used an empty string here, so you, at least, won't get a null reference error).}
You'll just have to do that for all of your lines requesting cookie values.
The point is, though, that anything can go in the "else" block that helps you handle what to do when the cookie values have been cleared/expired (which you must always expect). You could redirect to a page that requests information from the user to reset any "forgotten" configurations, or, if you want to persist the data no matter what, consider storing these values in a database, instead, as those values won't clear/expire.
One last thing, if this doesn't help:
If you find yourself wondering what value to store in the cookie (the default value you wish to specify), because you need to know, right then and there, what it was supposed to have remembered, then I am afraid it is time to reconsider how you have structured the flow of data.
Sorry, but I have done that, once upon a time, only with Session variables, and it wasn't pretty :)
If you need any help with the best way(s) to transfer data between web pages, check this very helpful, concise link from Mike Brind's website: http://www.mikesdotnetting.com/Article/192/Transferring-Data-Between-ASP.NET-Web-Pages
It should just be the following
if(Request.Cookies["BookingEnquiry"] == null)
{
return; // <- if BookingEnquiry is null we end this routine
}
// Normal code flow here...
or something similar

Format a property before displaying it

Hello StackOverflow experts,
I would like to know if it would be possible to use Ember.js' computed properties to modify the value of the property before returning to whatever object requests it.
Imagine this simple example:
I have a User object with mail property
When I set the property, I want the email address to change from first.last#example.com to first.last#anotherexample.com, then return it
When I request the property ( via User.get ) I want to get the modified property back.
I think it should be pretty simple by utilising another 'helper' property, like formatted_mail, where I would store and retrieve the formatted value, but I wonder if something like this can be done without additional model properties.
So far, I have this coffescript code, but I always get 'undefined' when reading the property, even though I set it before, so I suspect the value does not get saved by Ember anywhere:
mail: ( ( key, value ) ->
if arguments.length == 1
return this.get 'mail'
else
return value.split( '#' )[0] + '#anotherexample.com'
).property 'mail'
Thank you for your assistance!
You are close to solution.
As computed properties are always cached by default in Ember (you could disable this behaviour using .volatile()), you do not have to specify what to do when arguments.length is 1, except if you want to specify a default value.
So here it should looks like:
App.User = Ember.Object.extend({
mail: function(key, value) {
if (arguments.length === 2) {
return value.split('#')[0] + "#tieto.com";
}
return null;
}.property()
});
The return null just specify the default value.
When you set the mail property, it will cache the returned value and always returns it without recomputing this property.
Note that you can do that only because the mail property does not depend on other properties. If you were declaring it with .property('anotherProperty'), the mail property will be recomputed any time anoterProperty changes. So in the example above it will reset it to null.
You can try it in this JSFiddle.

Sitecore: Find the value of a field for a selected Item

I'm trying to create some custom code inside my Sub Layout.
I have to build a newsletter, the newsletter can be composed on a number of article.
An article can be composed by a title / Sub title / Header and image.
Can be, because the Sub title or the image are not mandatory.
To avoid any empty space / missing image in the newsletter email, I would like to create a specific HTML based on the content.
If there is no image, don't show the Image control, if there is no Sub title, don't show the Sub Title control;
To do that, I'm using the following code which is not working :(
Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase("master");
Sitecore.Data.Items.Item home = master.GetItem("/sitecore/content/Home");
if(home != null && home.Fields != null)
{
string name = home.Fields["Image"].Name; -> Which Fields["Image"] returns null.
}
Is there another way to retreive the field of the selected article ? As my code is not working at all, I don't understand how to retreive the Field value of my selected Item.
Thank you.
In your example, home.Fields is just checking to make sure that the Fields collection exists. You aren't checking if there is a value in the Image field before trying to extract the name.
You probably need something like this:
if(home != null && home.Fields != null && home.Fields["Image"] != null)
{
string name = home.Fields["Image"].Name;
}
Per your comments, it seems to be you are actually trying to pull the image field from the datasource of your component. If you want to conditionally check for the image field before doing something in that case, there are a lot of possible null exceptions that I would want to handle. The code should probably be something like:
var parent = ((Sitecore.Web.UI.WebControl)Parent);
if(parent != null){
Item dataSourceItem = string.IsNullOrWhiteSpace(parent.DataSource) ? null : Sitecore.Context.Database.GetItem(parent.DataSource);
if(dataSourceItem != null && dataSourceItem.Fields != null && dataSourceItem.Fields["Image"]!=null){
string name=dataSourceItem.Fields["Image"].Name;
}
}
Here is one simple way :
Sitecore.Context.Item.Fields["You field name"]