abp.io IdentityUser required properties - abp

following the documentation documentation I have no problem adding properties to IdentityUser, but if I want to add the RequiredAttribute to Name and Surname it is ignored, did I miss something or is it a limitation of the Blazor UI?
ObjectExtensionManager.Instance
.AddOrUpdateProperty<string>(
new[]
{
typeof(IdentityUserDto),
typeof(IdentityUserCreateDto),
typeof(IdentityUserUpdateDto)
},
"Name",
property =>
{
property.Attributes.Add(new RequiredAttribute());
}
);

Related

Using the MediaPicker property editor in custom property (Umbraco)

I want to create a custom property editor, that makes use of the media picker. Right now my controller looks like this:
angular.module("umbraco").controller("My.MediaCropperController",
function($scope, dialogService) {
$scope.mediaPicker = {
view: 'mediapicker',
value: null, // or your value
config: { disableFolderSelect: true, onlyImages: true }
};
});
And my view looks like this:
<umb-editor ng-controller="My.MediaCropperController" model="mediaPicker" ng-if="mediaPicker">
</umb-editor>
As I understand it, I need to create config object for built-in editors, then use in the template to show the editor. However when i bring my property editor into my backoffice, nothing is being shown. What am I doing wrong here?
This is my package manifest file:
{
//you can define multiple editors
propertyEditors: [
{
/*this must be a unique alias*/
alias: "My.MediaCropper",
/*the name*/
name: "My Media Cropper",
/*the html file we will load for the editor*/
editor: {
view: "~/App_Plugins/MediaCropper/mediacropper.html"
}
}
]
,
//array of files we want to inject into the application on app_start
javascript: [
'~/App_Plugins/MediaCropper/mediacropper.controller.js'
]
}
dialogService.mediaPicker rather than $scope.mediapicker ?
May be what is causing your error, just from comparing my script to yours.

Avoid serialization of properties

When I require to add a private property to an object (for view or logic control) that will be submitted to a rest api latter, is valid prefix the property with $$? This is tricky in cases when I have an object with a list of children and each child requires a private property that should not be sent.
{
name: 'my object',
items: [
{
name: 'my child',
$$editing: true
},
{
name: 'my other child',
$$editing: true
}
]
}
Yes, angularjs $http service uses the angular.toJson method by default.
All properties with $$ are filtered out, because angular uses such properties internally. (e.g. you may have seen the $$hashKey property, which is added by angular)
You can try:
console.log(angular.toJson({a:1, $$b:2, c: {x:2,$$_y:3}}))
results in "{"a":1,"c":{"x":2}}"

How to post many-to-many relational data to a restful api from AngularJS?

I have a Theme Management module in my web application. I'รถ using SequelizeJS in server side.
Models are:
module.exports = function(sequelize, DataTypes) {
var Theme = sequelize.define('Theme', {
name: DataTypes.STRING,
description: DataTypes.STRING
}, {
associate: function(models) {
Theme.belongsToMany(models.Option, { through: models.ThemeOptions })
},
tableName: 'themes'
});
return Theme;
};
module.exports = function(sequelize, DataTypes) {
var ThemeOptions = sequelize.define('ThemeOptions', {
}, {
tableName: 'theme_options'
});
return ThemeOptions;
};
module.exports = function(sequelize, DataTypes) {
var Option = sequelize.define('Option', {
key: DataTypes.STRING,
value: DataTypes.STRING
}, {
associate: function(models) {
Option.belongsToMany(models.Theme, { through: models.ThemeOptions })
},
tableName: 'options',
timestamps: false
});
return Option;
};
In /#/themes/create state, I want to create a theme with some options, like color codes.
I am creating a theme with
$http.post('/themes', themeData)
then with it's it, I am creating options. Finally I should post many-to-many data to theme options. So for a theme that has 10 options, I am posting 21 times.
What is the best way to post many-to-many data to a REST server?
Don't really know how you handle your routing or backend. Supposing you're using express and your options are previously created, I'd recommend creating a new post route for handling each ThemeOptions
app.post('/themeOptions', { ThemeId: 1, OptionId:2 });
and use that info to create a ThemeOptions instance to join a Theme with certain Option.
This could reduce your post quantity to the half + 1 (one for the Theme and one for each ThemeOption).
Another solution is to maybe manage an array of ThemeOptions and use ThemeOptions#bulkCreate to create them at once, using only 2 posts (one for the Theme and one for all the ThemeOptions.
Would be something like this:
app.post('/themeOptions', {
options: [{
ThemeId: 1,
OptionId:2
}, {
ThemeId: 1,
OptionId:3
}
// and so on...
});
Each of these solutions could involve more logic to manage each front end request, but could increase front end behavior as well.
A final (and more complex at the backend) solution would be to send a unique post sending both, the Theme and the Options array, and create all the ThemeOptions after creating the Theme
// frontend
app.post('/theme', {
theme: {
name: 'John',
description: 'Doe'
},
options: [2, 3 /* and so on ... */]
});
// backend
Theme.create(req.body.theme).on('success', function (theme) {
var options = req.body.options.map(function (option) {
return {
ThemeId: theme.id,
OptionId: option
};
});
ThemeOptions.bulkCreate(options);
})
In the Symfony2 world, there is a bundle, SonataAdminBundle, that generates admin interfaces. With the entity classes (here, Option and Theme), it generates all the pages, listing, creating and editing theses entities. It generates forms that handles many to many relationship. Here how it manages that :
The user consults the creation/edition form of the entity of any side of the ManyToMany relation. In the form, where it have to display the many to many association, it displays a <select>, with Select2 for instance, which is a <select> with some jQuery. Each element of the list is linked with the corresponding ID in the database, something like <option value="13456">Option #3</select>. For a many to many relationship, we can select multiple fields at the time. Internally, it builds an array of Option IDs with the <select>.
If we want to add a inverse entity on the fly (here, the inverse entity is Option, I think ...), there is a button that open ups an Option creation form, and once the new Option is added, it adds the newly created option in the <select>, so the user can add it in the form immediately.
Then, it sends the array of Option ID's built with the form.
I think this strategy could fit your needs.

Backbone.Collection.create() using Collection.url and not Model.url

I'm trying to create model objects on the fly using Backbone.Collection.create...but I note that the collection uses its url and not the model's url...
Is this how it suppose to work? Can I override it on the fly just for this particular .create()?
You can specify the options attribute that contain the url property :
Backbone.Collection.create({
key: "value",
...
}, { url : 'yourUrlHere' });

Backbone.js - Using new() in Model defaults - circular reference

Taking the following Model:
MyModel= Backbone.Model.extend({
defaults : {
myNestedModel:undefined,
},
initialize: function() {
this.set({myNestedModel: new MyNestedModel());
}
});
It has a single property named 'myNestedModel' which has the following definition:
MyNestedModel= Backbone.Model.extend({
defaults : {
myModel:undefined,
}
});
It too has a single Property name 'myModel'. Now if I create an instance of MyModel:
aModel = new MyModel();
The nested model will have been set in MyModel's initialize method. I then use JSON.stringify in a two step process:
// Use Backbone.js framework to get an object that we can use JSON.stringfy on
var modelAsJson = aModel.toJSON();
// Now actually do stringify
var modelAsJsonString = JSON.stringify(modelAsJson);
This works fine and I get the JSON representation of MyModel and it's property of MyNestedModel. The problem occurs when I use defaults, for example:
MyModel= Backbone.Model.extend({
defaults : {
new MyNestedModel(),
}
});
This causes a problem with JSON.stringify since it doesn't support circular references. I assume the circular reference is being created because all instances of MyModel share the same instance of MyNestedModel. Whereas the initialize method creates a new nested model for each instance.
Questions:
Is my understanding of defaults:{} being the 'cause' of the
problem correct?
From a question I posted recently I got the
impression I should be using defaults for all properties. If that is
the case, how should I be using defaults in the scenario presented
in this post/question?
Can someone clarify the use of defaults:{}
with regards to when the value applies, when it's overridden and
whether instances share the same default 'instances'?
Defaults is used only for attributes inside your model ( the data in the model ), and whenever you create your model it takes the values from defaults and sets the attributes. e.g.
User = Backbone.Model.extend({
defaults : {
rating : 0
}
})
User1 = new User({ name : 'jack', email : 'jack#gmail.com' });
User2 = new User({ name : 'john', email : 'john#gmail.com' });
User1.set({ rating : 2 });
Now your two models when called with toJSON will print
{
rating: 2,
name: 'jack',
email: 'jack#gmail.com'
}
{
rating: 0,
name: 'john',
email: 'john#gmail.com'
}
Since defaults is an object, every value you place there is evaluated immediately so :
defaults : {
rating : defaultRating()
}
will call defaultRating() - not everytime when you initialize the model, but immediately ( in the extend method )
You should use defaults for models where you need some data to exist on the creating of the model ( e.g. new myModel() )
In your example you have the following mistakes :
1.set a value without a property
defaults : {
PROPERTY : new Model()
}
2.you don't need such an option for your defaults - you should place there only attributes ( data ) for the model
Defaults applies always as long as it is not replaced by a new defaults in an extended model e.g.
var Model = Backbone.Model.extend({ defaults : { alpha : 'beta' } });
var myModel = Model.extend({ defaults : { beta : 'gama' } });
now your myModel when initialized will have
{ beta : 'gama' } // alpha : 'beta' will not be set as value, because it is replaced

Resources