{"id":15877886,"url":"https://github.com/k1r0s/angular2-srp-showcase","last_synced_at":"2025-06-18T18:34:31.028Z","repository":{"id":86020359,"uuid":"99411813","full_name":"k1r0s/angular2-srp-showcase","owner":"k1r0s","description":"Angular 2+ demo about SRP, AOP techniques using kaop-ts","archived":false,"fork":false,"pushed_at":"2017-10-21T16:14:51.000Z","size":61,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-01T18:50:20.426Z","etag":null,"topics":["advice","angular","aspect-oriented-programming","demo","separation-of-concerns"],"latest_commit_sha":null,"homepage":"https://angular2-kaop.firebaseapp.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/k1r0s.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-08-05T09:05:57.000Z","updated_at":"2024-11-01T19:25:43.000Z","dependencies_parsed_at":"2023-03-03T16:45:26.204Z","dependency_job_id":null,"html_url":"https://github.com/k1r0s/angular2-srp-showcase","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/k1r0s/angular2-srp-showcase","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k1r0s%2Fangular2-srp-showcase","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k1r0s%2Fangular2-srp-showcase/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k1r0s%2Fangular2-srp-showcase/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k1r0s%2Fangular2-srp-showcase/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/k1r0s","download_url":"https://codeload.github.com/k1r0s/angular2-srp-showcase/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k1r0s%2Fangular2-srp-showcase/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260609568,"owners_count":23035957,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["advice","angular","aspect-oriented-programming","demo","separation-of-concerns"],"created_at":"2024-10-06T02:04:46.711Z","updated_at":"2025-06-18T18:34:26.015Z","avatar_url":"https://github.com/k1r0s.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"### Single Responsibility Principle, Aspect oriented programming example in Angular --\u003e\n\nThis is an example about separation of concerns in Angular applications. This example is quite simple and maybe cannot be a solution for complex problems. Learn more about:\n\n- https://en.wikipedia.org/wiki/Single_responsibility_principle\n- https://en.wikipedia.org/wiki/Aspect-oriented_programming\n\nThis example is about removing infrastructure code from components by applying abstraction and modularity using SRP, AOP technique.\n\nThe following example is about a component that must contain a list of autors which have several posts, simple as that. There are hundreds of approaches but many of them do not apply separation of concerns and code readability.. and probably, if you have to repeat that process in different scenarios you will run duplication and code scattering problems.\n\n\u003eThis example app is about kaop-ts capabilities. You should'nt see this as a genuine SRP, AOP example. Real world problems with **Cross Cutting Concerns** are harder than these... but, first of all you should know what tools exists against code repetition (CCC).\n\n##### There we go:\n\nThis repo has two branches:\n\nmaster -\u003e branch with the examples\nnormal-oop -\u003e branch without advices with CCC\n\nThis application example has the following features:\n\n- When the app starts should fetch a resource (writers)\n- While fetching a \"loading\" dialog should be placed on the UI\n- The resource should be cached, so following calls should be avoided\n- The resource should be placed as a list of writers\n- The user can click on each element to see a summary of that resource instance\n- For whatever reason selecting a writer from 'South Elvis' will throw an error\n- For whatever reason if there was an error during the selection it should be presented to the user\n- That summary is presented as a Dialog with several info\n- The user can \"close\" the dialog or \"see posts\"\n- If the user clicks on \"see posts\" the app should render another component\n- That component should fetch a resource (posts) related to the selected user\n- Also while fetching, a \"loading\" dialog should be placed on the UI\n- Also following calls to the same resource should be avoided and cached\n\n## async calls\n\n- create a component (WriterComponent)\n- describe a Pattern (Interface + Advice) of (component that must trigger an ajax request and receive a response)\n- create an Interface called (ResourceContainer)\n```typescript\nexport interface ResourceContainer\u003cM = any\u003e {\n  service: CommonRequest,\n  servicePath?: string\n  onResourceFulfit?(data?: M[]): void\n}\n```\n- create behavior (Advice) called (ResourceContainerFetch)\n```typescript\nexport const ResourceContainerFetch = beforeMethod\u003cResourceContainer\u003e(function(meta) {\n  const resourcePromise = meta.scope.service.getResource(meta.args[0] || meta.scope.servicePath).toPromise()\n  if (typeof meta.scope.onResourceFulfit === \"function\") {\n    resourcePromise.then(meta.scope['onResourceFulfit'].bind(meta.scope))\n  }\n  resourcePromise.then((data) =\u003e {\n    meta.args.push(data)\n    this.next()\n  })\n})\n```\n- create a service that fits that behavior (service must fit Behavior rather than **component needs**)\n- our component should implement ResourceContainer\n- then our ResourceContainerFetch should be declared only at `setup` method which is defined as the only trigger for that action (customizable).\n\n## dialog\n\n- describe a pattern that dialog holders must implement\n- create an interface called DialogHolder\n```typescript\nexport interface DialogHolder {\n  dialogFactory: MdDialog\n  dialogRef: MdDialogRef\u003cany\u003e\n  onDialogClose?(): void\n}\n```\n- describe a Pattern for that components\n```typescript\nexport const OpenDialog = (dialogComponent, errorDialogComponent = ErrorDialogComponent) =\u003e {\n  return afterMethod\u003cDialogHolder\u003e(function(meta) {\n\n    meta.scope.dialogRef = meta.scope.dialogFactory.open(\n      meta.exception ? errorDialogComponent : dialogComponent,\n      { data: meta.result }\n    )\n\n    if (typeof meta.scope.onDialogClose === \"function\") {\n      meta.scope.dialogRef.afterClosed()\n      .subscribe(meta.scope.onDialogClose.bind(meta.scope))\n    }\n  })\n}\n```\n- our component should implement DialogHolder\n- in this case any method can trigger OpenDialog so we need to decorate that method, that's all. Note that in the advice we check if `onDialogClose` is defined on annotated instance we subscribe that function.\n- also if an exception is declared by another advice then errorDialogComponent will be rendered instead.\n\n\u003e There are more examples like 'method cache', 'loading-dialog', 'exception handling'.. more to come\n\n##### See in action\n\n```bash\ngit clone https://github.com/k1r0s/angular2-srp-showcase.git\ncd angular2-srp-showcase\nnpm install\nng serve\n```\n\nBy default subsequent calls are cached by `cache-holder.ts`, look over application tab in developer tools to remove cache.\n\n##### Detailed Explanation\n\nhttps://hackernoon.com/angular-tutorial-separation-of-concerns-using-es7-decorators-ed6c9756265\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fk1r0s%2Fangular2-srp-showcase","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fk1r0s%2Fangular2-srp-showcase","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fk1r0s%2Fangular2-srp-showcase/lists"}