I have pattern:
export class Items {
key: string;
item: string;
childItems: {key: string; item: string; };
}
And have some Service is generating parent key:
export class OptionService {
private dbPath = '/items';
itemsRef: AngularFireList<Items> = null;
constructor(private db: AngularFireDatabase) {
this.itemsRef = db.list(this.dbPath);
}
createItem(item: Items): void {
this.itemsRef.push(item);
}
How do may generate key in "childItems"? I need make unique key for this element when I will add property value. Please help me find resolve.
Related
I have the following custom directive in Angular11.None of the variables are replaced in the test component and the [rowClick] is taking value as string instead of an object. not sure i am not able to pass object as directive input parameter.
#Component({
selector: 'fake-component',
template: `<table><tr
[rowClick] = "{commands: ['/enhanced-audits/builder/detail/123'], externalUrl: false}"
[rowClickGate]="testObservable$"
[rowClickData]="testData"
(onRowClicked)="rowClickHandler($event)"><td>Row 1 Col 1</td></tr></table>`
})
class RowClickTestComponent {
public selectedWorkflowOwnerId: number;
public selectedSectionName: string;
public isWorkflowTask: boolean;
public testData = {
ownerId: 123,
sectionName: 'test section name',
isWorkflowTask: true
}
rowClickHandler(rowClickData: RowClickData): void {
}
testObservable$ = new Observable((subscriber) => {
subscriber.next(true);
subscriber.complete();
});
}
Directive:
export class RowClickDirective implements OnInit {
#Input('rowClick')
options: RouterNavigateParams;
#Input('rowClickGate')
gate$?: Observable<boolean>;
#Input() rowClickData: RowClickData;
#Output() onRowClicked: EventEmitter<RowClickData> =
new EventEmitter<RowClickData>();
}
I need to save this Objects into a SQL/Drift DB, how can/should I design die Tables/Rows for an efficient mapping?
Here is are examples of a (deep)nested union class. It itself is a union class and also has a field which in itself is also a union class again.
What is the best way to deal with this?
#freezed
class TemplateDto with _$TemplateDto {
const factory TemplateDto({
required String templateID,
required String userID,
required String organisationID,
required bool shareWithOrg,
required bool shareGlobal,
required TemplateDataDto templateDataDto,
}) = _TemplateDto;
...
}
#freezed
class TemplateDataDto with _$TemplateDataDto {
const TemplateDataDto._();
const factory TemplateDataDto.templatePack({
required String templateName,
required List<String> templatesInPack,
}) = TemplatePackDto;
const factory TemplateDataDto.homeworkTemplate({
required String templateName,
required HomeworkDataDto homeworkDataDto,
}) = HomeworkTemplateDto;
const factory TemplateDataDto.XXXX({
...
}) = XXXTemplateDto;
...
}
#freezed
class HomeworkDataDto with _$HomeworkDataDto {
const HomeworkDataDto._();
const factory HomeworkDataDto.oneTimeHomework({
required String homeworkName,
required String homeworkDescription,
required bool isActive,
#JsonKey(
includeIfNull: true,
defaultValue: false,
)
required bool isPartOfMultiHomework,
required DateTime dueDate,
}) = _OneTimeHomeworkDto;
const factory HomeworkDataDto.multiOneTimeHomework({
...
}) = _MultiOneTimeHomeworkDto;
const factory HomeworkDataDto.recurringHomework({
...
}) = _RecurringHomeworkDto;
...
}
I've just learned about serenity-js and am giving it a go. I'm following the tutorial and noticed the follow example:
james.attemptsTo(
Start.withAnEmptyTodoList(),
AddATodoItem.called('Buy some milk')
)
The task for Start:
export class Start implements Task {
static withATodoListContaining(items: string[]) { // static method to improve the readability
return new Start(items);
}
performAs(actor: PerformsTasks): PromiseLike<void> { // required by the Task interface
return actor.attemptsTo( // delegates the work to lower-level tasks
// todo: add each item to the Todo List
);
}
constructor(private items: string[]) { // constructor assigning the list of items
} // to a private field
}
I really like this syntax and would like to continue this setup with more starting scenario's.
What would be the proper approach to accomplish this?
For anyone having the same question this is how I resolved it (found a similar setup going through the serenity-js repo):
// Start.ts
export class Start {
public static withATodoListContaining = (items: string[]): StartWithATodoListContaining => new StartWithATodoListContaining(items);
}
// StartWithATodoListContaining.ts
export class StartWithATodoListContaining implements Task {
static withATodoListContaining(items: string[]) {
return new StartWithATodoListContaining(items);
}
performAs(actor: PerformsTasks): PromiseLike<void> {
return actor.attemptsTo(
// todo: add each item to the Todo List
);
}
constructor(private items: string[]) {
}
}
I would do like to have public access the private property where objects are stored on the current ValidationController as when we issue addObject().
From this blog:
http://www.jujens.eu/posts/en/2017/Jan/24/aurelia-validation/
I am trying to validate not only a WELL KNOWN object but ALL objects registered in the ValidationController
Let me explain a little bit, I had an interface called
export interface IRuleValidator {
addRules(model:any): void;
}
and classes that implement such interface
export class AddressRuleValidator implements IRuleValidator {
addRules(address: Address) {
ValidationRules
.ensure((a: Address) => a.address)
.required()
.on(address);
}
}
export class EmailRuleValidator implements IRuleValidator {
addRules(email: Email) {
ValidationRules
.ensure((e: Email) => e.email)
.required()
.on(email);
}
}
export class PhoneRuleValidator implements IRuleValidator {
addRules(phone: Phone) {
ValidationRules
.ensure((p: Phone) => p.phone)
.required()
.on(phone);
}
}
#inject(AddressRuleValidator, PhoneRuleValidator, EmailRuleValidator)
export class PlayerRuleValidator implements IRuleValidator {
private readonly addressRuleValidator: IRuleValidator;
private readonly phoneRuleValidator: IRuleValidator;
private readonly emailRuleValidator: IRuleValidator;
constructor(addressRuleValidator: IRuleValidator, phoneRuleValidator: IRuleValidator, emailRuleValidator: IRuleValidator) {
this.addressRuleValidator = addressRuleValidator;
this.phoneRuleValidator = phoneRuleValidator;
this.emailRuleValidator = emailRuleValidator;
}
addRules(player: Player) {
ValidationRules
.ensure((p: Player) => p.firstName)
.required()
.on(player);
if (player.addresses && player.addresses.length > 0)
player.addresses.map(address => this.addressRuleValidator.addRules(address));
if (player.phones && player.phones.length > 0)
player.phones.map(phone => this.phoneRuleValidator.addRules(phone));
if (player.emails && player.emails.length > 0)
player.emails.map(email => this.emailRuleValidator.addRules(email));
}
}
#inject(PlayerRuleValidator)
export class ScoreRuleValidator implements IRuleValidator {
private readonly playerRuleValidator: IRuleValidator;
constructor(playerRuleValidator: IRuleValidator) {
this.playerRuleValidator = playerRuleValidator;
}
addRules(score: Score) {
ValidationRules
.ensure((s: Score) => s.factor)
.required()
.on(score);
if (score.player) { this.playerRuleValidator.addRules(score.player); }
}
}
Each class knows how to validate the object passed to it and delegates to other classes the validation of "child" objects.
i.e.: score has a player and a player has emails.
Score knows how to validate to itself and delegates to player his own validation and player do the same with emails, phones, buildin all "the chain" down.
Thus the entire process of building a "validation chain" starts calling addRules() on the root object of the graph.
Suppose that we have an score object: We resolve from "the container" a ruleValidator for Score and starts buildind the validation chain as follows.
#inject(ScoreRuleValidator)
export class ScoreList extends BaseViewModel {
public isOk: boolean;
public score: Score
................ code removed for brevity (validation controller code )
#inject(ScoreRuleValidator)
constructor(ruleValidator: IRuleValidator) {
................ code removed for brevity (validation score object creation)
ruleValidator.addRules(this.score) //this call will start all the validation chain registration
this.validationController.validateTrigger = validateTrigger.changeOrBlur;
this.validationController.subscribe(event => this.validateAll())
}
}
private validateAll() {
this.validator
.validateObject(this.model)
.then(results => this.isOk = results.every(result => result.valid));
//HERE GOES THE PROBLEM SINCE ONLY SCORE is known, and what about score.player, and score.player.addresss[], score.player.phones[], score.player.emails[] and so on in the graph
//I WILL NEED to traverse all the chain and since ValidationController has track of those object will be greet to have access to them
}
HERE GOES THE PROBLEM SINCE ONLY SCORE is known, and what about score.player, and score.player.addresss[], score.player.phones[], score.player.emails[] and so on in the graph?.
I WILL NEED to traverse all the chain and since ValidationController has track of those object will be great to have access to it.
Meanwile an option is refactor the interface a rewrite the validator classes as follows:
export interface IRuleValidator {
addRules(model:any, models:any[]): void;
}
and pass an empty array from the root of the chain collecting all those objects.. like so..
export class AddressRuleValidator implements IRuleValidator {
addRules(address: Address, models: any[]) {
ValidationRules
.ensure((a: Address) => a.type)
.required()
.on(address);
models.push(address);
}
and kick the process.. with an empty array []
const objects: any[] = [];
ruleValidator.addRules(this.score, [])
But since we alreay have this property private on the ValidationController, please make it public.. (I will take care of not touching it, just read it)
BR
(then... the final method for validateAll should be like this)
private async validateAll() {
for (let model of this.models) {
let results = await this.validator.validateObject(model);
if (results.some(result => !result.valid)) {
this.isOk = false;
return;
}
}
this.isOk = true;
}
A deep look to the callback is the answer.
validationController.subscribe(event => this.validateAll())
the event object passed to the callback is an array of ValidateResult[]
the ValidateResult type implements the following interface.
export declare class ValidateResult {
rule: any;
object: any;
propertyName: string | null;
valid: boolean;
message: string | null;
private static nextId;
/**
* A number that uniquely identifies the result instance.
*/
id: number;
/**
* #param rule The rule associated with the result. Validator implementation specific.
* #param object The object that was validated.
* #param propertyName The name of the property that was validated.
* #param error The error, if the result is a validation error.
*/
constructor(rule: any, object: any, propertyName: string | null, valid: boolean, message?: string | null);
toString(): string | null;
}
so the object/s validated is already there in the event object
we could simplyfy the code as follow to update a field to signal if the htlm for is ready.
this.validationController.subscribe(validateEvent => this.isFormValid = validateEvent.results.every(result => result.valid));
I am new to Aurelia. I have a WebApi that will return some data that I would like to populate into my exported model and then display the info on the screen.I'm thinking it would go into my run event but am not sure. Can anybody tell me how to do this . Any information would be most appreciated. My code is below.
--Jason
import 'fetch';
import {HttpClient, json} from 'aurelia-fetch-client';
import {inject} from 'aurelia-dependency-injection';
declare var window: { wcApiUrl: string, wcAmtInstanceId: string };
#inject(HttpClient)
export class BureauModUpdate {
files: string;
constructor(private http: HttpClient) {
http.configure(x => {
x.defaults.headers = { 'Authorization': 'Basic ' + window.wcAmtInstanceId }
});
}
public run(): void {
//Would I put it here ??
}
upload(): void {
var form = new FormData()
for (var i = 0; i <= this.files.length; i++) {
form.append('file', this.files[i])
this.http.fetch(window.wcApiUrl + '/Lookup/BureauModUpdate/CreateBureauModUpdates', {
method: 'post',
body: form
})
}
}
}
export class BureauModUpdateHistory {
public IndexId: number;
public UploadID:number;
public EmployeeNum: number;
public filename: string;
public Bureau: string;
public UploadedDate: Date;
public UploadedStatus: string;
public ErrorInfo: string;
public RecordCount: number;
}
To make something happen when the page loads, use the attached() Aurelia component lifecycle method, like this:
attached() {
// do something here
}
For more information on the Component Lifecycle, see the documentation on Aurelia's DocHub.
Example using Fetch to get data:
For getting HTTP data using fetch (or any other web service), you need to use an async call (using .then to chain the next event). For example:
this.http.fetch(url).then(response => {
this.data = response;
}
Then, just bind your data to this.data (depending on what type of data you're getting). For example:
<template>
Hello, ${data.fname}!
</template>