{"id":2967,"date":"2021-01-01T10:56:03","date_gmt":"2021-01-01T15:56:03","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=2967"},"modified":"2021-01-01T10:56:03","modified_gmt":"2021-01-01T15:56:03","slug":"translations-in-a-angular-library","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/angular\/translations-in-a-angular-library\/","title":{"rendered":"Translations in a Angular Library"},"content":{"rendered":"\n<p>Developing a UI library for Angular, I had strings that needed be hardcoded.  The question became how do I deal with them.  I did not want to embed in <a href=\"https:\/\/github.com\/ngx-translate\/core\" data-type=\"URL\" data-id=\"https:\/\/github.com\/ngx-translate\/core\">ngx-translate<\/a> into the library.  I wanted the user to have the ability to modify the strings as well.  So I created a LanguageService.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { Injectable } from '@angular\/core';\r\nimport {BehaviorSubject, Observable, Subscription} from \"rxjs\";\r\n\r\n@Injectable({\r\n  providedIn: 'root'\r\n})\r\nexport class LanguageService {\r\n\r\n  private _editLabel: string = \"edit\";\r\n  private _deleteLabel: string = \"delete\";\r\n  private _undoLabel: string = \"undo\";\r\n  private _clearLabel: string = \"clear\";\r\n  private _saveLabel: string = \"save\";\r\n  private _searchLabel: string = \"search\";\r\n\r\n  public editSub:BehaviorSubject&lt;string>;\r\n  public deleteSub:BehaviorSubject&lt;string>;\r\n  public undoSub: BehaviorSubject&lt;string>;\r\n  public clearSub: BehaviorSubject&lt;string>;\r\n  public saveSub: BehaviorSubject&lt;string>;\r\n  public searchSub: BehaviorSubject&lt;string>;\r\n\r\n  constructor() {\r\n    this.editSub = new BehaviorSubject&lt;string>(this._editLabel);\r\n    this.deleteSub = new BehaviorSubject&lt;string>(this._deleteLabel);\r\n    this.undoSub = new BehaviorSubject&lt;string>(this._undoLabel);\r\n    this.clearSub = new BehaviorSubject&lt;string>(this._clearLabel);\r\n    this.saveSub = new BehaviorSubject&lt;string>(this._saveLabel);\r\n    this.searchSub = new BehaviorSubject&lt;string>(this._searchLabel);\r\n  }\r\n\r\n\r\n  get editLabel(): string {\r\n    return this._editLabel;\r\n  }\r\n\r\n  set editLabel(value: string) {\r\n    this._editLabel = value;\r\n    this.editSub.next(value);\r\n  }\r\n\r\n  get deleteLabel(): string {\r\n    return this._deleteLabel;\r\n  }\r\n\r\n  set deleteLabel(value: string) {\r\n    this._deleteLabel = value;\r\n    this.deleteSub.next(value);\r\n  }\r\n\r\n  get undoLabel(): string {\r\n    return this._undoLabel;\r\n  }\r\n\r\n  set undoLabel(value: string) {\r\n    this._undoLabel = value;\r\n    this.undoSub.next(value);\r\n  }\r\n\r\n  get clearLabel(): string {\r\n    return this._clearLabel;\r\n  }\r\n\r\n  set clearLabel(value: string) {\r\n    this._clearLabel = value;\r\n    this.clearSub.next(value);\r\n  }\r\n\r\n  get saveLabel(): string {\r\n    return this._saveLabel;\r\n  }\r\n\r\n  set saveLabel(value: string) {\r\n    this._saveLabel = value;\r\n    this.saveSub.next(value);\r\n  }\r\n\r\n  get searchLabel(): string {\r\n    return this._searchLabel;\r\n  }\r\n\r\n  set searchLabel(value: string) {\r\n    this._searchLabel = value;\r\n    this.searchSub.next(value);\r\n  }\r\n}\r\n<\/code><\/pre>\n\n\n\n<p>The idea is quiet simple.  I define out the string that I want to have or may want translated.  Each string was given a &#8220;default&#8221; value so there would be no requirement for a user to translate these strings or even interact with my service, if they didn&#8217;t need to.<\/p>\n\n\n\n<p>Next, I created BehaviorSubjects for these values and in the setters, I made the call to pass the value.  My UI components can get the values of these strings immediately with the getter, and subscribe to get any changes to those strings later.  Thus making it possible to change the language on the fly.<\/p>\n\n\n\n<p>Now the user of my library if they desire only needs to call the setters on my service to pass in the new text or translated text if they want it changed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Developing a UI library for Angular, I had strings that needed be hardcoded. The question became how do I deal with them. I did not want to embed in ngx-translate into the library. I wanted the user to have the ability to modify the strings as well. So I created a LanguageService. The idea is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2968,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[281],"tags":[269],"series":[329],"class_list":["post-2967","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular","tag-angular","series-form-components"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/01\/globe-110775_640.jpg?fit=640%2C341&ssl=1","jetpack-related-posts":[{"id":3029,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/angular-material-loading-spinner\/","url_meta":{"origin":2967,"position":0},"title":"Angular Material Loading Spinner","author":"Jeffery Miller","date":"May 3, 2021","format":false,"excerpt":"Just about every project I need to have at least one loading spinner to indicate to the user that data is being loaded and to wait. My recent project I found that to be no exception. I wanted to come up with something that I thought was a little nicer\u2026","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2943,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/angular-material-string-component\/","url_meta":{"origin":2967,"position":1},"title":"Angular Material String Component","author":"Jeffery Miller","date":"January 4, 2021","format":false,"excerpt":"Create a compnent for Display\/Edit\/Delete of a string using Angular Material mat-form-field.","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/application-1883453_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/application-1883453_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/application-1883453_640.jpg?fit=640%2C426&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":2951,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/angular-material-search-field\/","url_meta":{"origin":2967,"position":2},"title":"Angular Material Search Field","author":"Jeffery Miller","date":"January 25, 2021","format":false,"excerpt":"Angular Material Search Field component using mat-form-field to create a reusable component for searching.","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/search-bar-4999181_640.jpg?fit=640%2C225&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/search-bar-4999181_640.jpg?fit=640%2C225&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/search-bar-4999181_640.jpg?fit=640%2C225&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":2988,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/angular-structural-directive-onsize\/","url_meta":{"origin":2967,"position":3},"title":"Angular Structural Directive onSize","author":"Jeffery Miller","date":"January 18, 2021","format":false,"excerpt":"Creating an angular structural directive to operate on screen resolution.","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/01\/plan-2092499_640.jpg?fit=640%2C435&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/01\/plan-2092499_640.jpg?fit=640%2C435&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/01\/plan-2092499_640.jpg?fit=640%2C435&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":2946,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/angular-material-checkbox\/","url_meta":{"origin":2967,"position":4},"title":"Angular Material Checkbox","author":"Jeffery Miller","date":"January 11, 2021","format":false,"excerpt":"Create a compnent for Display\/Edit of a checkbox using Angular Material mat-form-field.","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/checklist-2549229_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/checklist-2549229_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/checklist-2549229_640.jpg?fit=640%2C426&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":2940,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/tips-tricks-for-an-angular-material-library\/","url_meta":{"origin":2967,"position":5},"title":"Tips\/Tricks for an Angular Library","author":"Jeffery Miller","date":"December 21, 2020","format":false,"excerpt":"Tips and tricks for building an Angular Material Library.","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/start-2465624_640.jpg?fit=640%2C425&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/start-2465624_640.jpg?fit=640%2C425&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/start-2465624_640.jpg?fit=640%2C425&ssl=1&resize=525%2C300 1.5x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/2967","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=2967"}],"version-history":[{"count":1,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/2967\/revisions"}],"predecessor-version":[{"id":2969,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/2967\/revisions\/2969"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/2968"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=2967"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=2967"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=2967"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=2967"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}