Can I use one line initialization of a blank address and have validation - angular2-forms

I recently started working with Angular 2 and reactive forms. What I'm trying to accomplish is simple: create an array inside a form and let user push new objects into it (say list of user addresses to which user can add new addresses - standard FormArray). That's quite simple (and it's all described well in the documentation) but I'd like to be able to automatically validate user's input as well. I know I can do this by simply pushing a group like this:
this.formBuilder.group({
country: ['', Validators.required],
city: ['', Validators.required],
...
})
but I've got a model that represents an address instance and I would like to use it like that:
this.formBuilder.group(new Address())
that's actually how I do it right now (without validation).
My question is: can I use this one line initialization of a blank address and somehow have the validation without explicitly defining my validators every time I push new blank address?
If my question isn't clear enough, I'll answer all of your questions.

This could be an option for you:
this.formBuilder.group(new Address(),
{validator: (fg: FormGroup) => this.attachValidators(fg)})
Basically setting a custom validator, which goes through the individual controls of the address collection and sets their individual validators property as desired. See below:
//helper method
private attachValidators(address: FormGroup)/*: ValidationErrors */ {
for (let ctrlName of Object.keys(address.controls)) {
address.get(ctrlName).setValidators(Validators.required);
}
}
May be too much, if you consider the repetitive assignment of validators

Related

Updating username across database

I've just started developing an app and having played about with Firebase before I figured it'd be a useful solution to having data stored server side.
I'm at the point where I've got a fully functional login and registration system which takes you to the app, but I've made it so that you require a 'username' before you can get passed the 'further registration' page (where the user sets up their profile information).
Currently, I've got a little note telling the user that they will be unable to update their username after setting it - however I don't really like the idea of this although I feel like I have no choice which is why I'm asking.
If I have multiple uses of the username in multiple places, like so:
{
users: {
id1234: {
username: "SomeUser123",
age: 20
}
}
posts: {
id445: {
title: "Some title",
content: "Some content",
postedBy: "someUser123"
}
}
}
How would I go about updating that person's username so that it also updates the post's username field (and likely several other places) in Swift? Or would the best option be to not allow a user to update their name? Which would be a shame.
Two Methods come to mind
1. Easy Route
If you're certain that you'll only be using username in those two places, then I'd just create references to them and simply update their value. This method is easy but obviously not scalable.
let userReference = FIRDatabase.database().reference().child("users/id1234")
userReference.updateChildValues([
"values": [
"sample0",
"sample1"
]
])
For the posts one, you'd want to filter first by postedBy before updating the value
2. Multi-path Route
This is the most scalable option and I'd recommend you reading this blog about it.
You can use updateChildValues for that.
let uniqueId = "id1234" //In your case
let newName = "NewUserName"
let ref = FIRDatabase.database().reference().child("users").child(uniqueId)
ref.updateChildValues(["username":newName])
Or you can also use setValue for single field update
ref.setValue(["username":newName])
Perhaps the easiest way is to store everything using the Firebase uid, but maintain a separate table of displayName for each uid, and then use the uid for the data layer, and displayName for the presentation layer.
This way, you only have to maintain the displayName in one place.

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.

Big Commerce Custom Fields

I'm planning on allowing a client to provide a couple codes for each product that I'll need to reference with Javascript on the product pages.
Basically my plan was to use the Big Commerce's 'custom fields' to do so, but I'm having trouble spitting out the custom fields onto the product pages. I've been looking all over for some type of GLOBAL variable that allows me to reference custom fields, but I'm coming up dry. I would think there would be some type of GLOBAL array with all the custom fields in it, or a way to reference them by name directly.
Am I blind, or is there just no way to do this directly in the BC template file?
Thanks.
In Bigcommerce the custom fields can generally be found within the ProductOtherDetails.html Panel which contains a Snippet named ProductCustomFieldItem.html. This snippet has the markup for each custom field that the system outputs.
Inside of the ProductCustomFieldItem.html Snippet are the two codes you are looking for: %%GLOBAL_CustomFieldName%% and %%GLOBAL_CustomFieldValue%%.
I ran into this as well - given that it's quite a long time later, I'm supposing there's no better answer - a decent amount of searching turned up nothing useful as it seems all you can do is output the full set of custom fields as a set of divs.
So, I output them into a div which was hidden:
<div id="fpd-custom-fields" style="display:none;">
%%SNIPPET_ProductCustomFields%%
</div>
and then set up a javascript function to get the value based on the name:
function getCustomFieldValue(label)
{
var value = '';
$('#fpd-custom-fields div.Label').each(function()
{
if($(this).text().toLowerCase() == (label.toLowerCase() + ':'))
{
value = $('div.Value', $(this).parent()).text().trim();
}
});
return value;
}
Doesn't feel quite right as it's not a very clean solution, but was the best I could come up with unfortunately!

grails: how to properly edit/update a collection?

I just wasted half a day trying to figure this out, reading about some workarounds, and thinking "it can't be that bad - there must be a straightforward to do edit a collection in Grails, whethere using scaffolded views or my own."
Let's say I have this domain object:
class TreeGroup {
String name
List<Tree> trees
static hasMany = ['trees': MyTree]
}
Just to explain the choice of data structure - I need my records to be unique, but in the order I set. That's why I chose List, AFAIK one cannot rely on order in a Set. So there are 2 pieces to this question - 1) how to remove from any Collection, for example a Set, 2) is List the best replacement for Set in this context (preserving order).
I want to be able to create a group record with no trees in it and make 4 updates:
edit/save
edit the group record to reference 2 trees A and B
add another tree C
remove A
remove B and C
And obviously, I want the desired state after every step. Currently though, I can only add records, and if I even edit/save to list, the list elements are added to it again.
I am using the multiple select tag for this. It looks like this:
<g:select name="trees" from="${allTrees}" optionKey="id"
multiple="true" class="many-to-many"
value="${trees ? trees*.id : treeGroupInstance?.trees*.id}" />
and that's fine, in the sense that it generates an HTTP header with these variables on update:
_method:PUT
version:19
name:d5
trees:1
_action_update:Update
But the data binder only adds new elements, it never lets you edit a list.
What is the cleanest way to do it ? Is it me, not reading something obvious, or is this a design flaw of grails data binding (and of so, when/how will it be fixed) ?
Is there a way perhaps via a hidden HTTP parameter to clear the list before (re)adding elements ?
Thanks
I ended up doing this:
private repopulate(def domainObject, String propertyName, Class domainKlaz) {
if (params[propertyName] != null) {
domainObject[propertyName].clear()
domainObject[propertyName].addAll(
params[propertyName].collect { domainKlaz.get(it) }
)
}
}
and I am calling it in update controller method before save(), for every collection. OMG how ugly.

How do I filter out attributes that shouldn't be in a POST request in Backbone?

I have a Rails application with the backbone-rails gem. Which works out fine but Backbone tries to send a request with all the attributes of the model. Is there a way I can filter out some of the attributes that will be POST'd on an update/new? This would work great for those virtual attributes and attributes that can't be mass assigned.
There is no harm in posting attributes that cannot be mass assigned. You will see a warning, but everything will work.
There are basically two ways of actually removing unwanted attributes. The first is to customize the Model's toJSON(). For example:
myModel = Backbone.Model.extend({
function: toJSON() {
var json = _.clone(this.attributes);
delete json.somethingIdontWant
delete json.somethingElse
return json
}
})
The second, and less clean way, is to explicitly pass the data in your call to Model.save(). If you are using the default Backbone.sync() method, then this data will be used instead. For example:
mything.save({
data: {just: "the stuff", that: "i want to post"}
})
You can probably figure out a way to generalize either of those approaches, depending on which one works for you.

Resources