0

I was making a table where user can do inline edit to its data. I got the code and made some tweaks according to my needs and it is working. But there I came across a code:

template: `
    <ng-container *ngTemplateOutlet="currentView"></ng-container>
  `

In this link what is 'currentView' referring to? I want to use this in my own code. What changes do I need to make this work?

  • It refers to an `ngTemplate`. Did you read [this documentation](https://angular.io/api/common/NgTemplateOutlet) ? Can you be more precise about what you don't understand ? – Arnaud Denoyelle Sep 14 '21 at 13:37
  • @ArnaudDenoyelle as you can see in the link,there is nothing mentioned about "currentView" other than that `editable.component.ts ` file. I want to find out where is that "currentView" coming from. I tried to use this code in my system and its not working –  Sep 14 '21 at 13:43
  • @ArnaudDenoyelle I tried to use this code in my project and this error is coming `core.js:6479 ERROR TypeError: Cannot read properties of undefined (reading 'tpl') ` while no error is being shown in the stackblitz file –  Sep 14 '21 at 13:45
  • 1
    This is an important topic and historically `ngTemplateOutlet` has been under-documented. Although as @ArnaudDenoyelle mentioned, it recently found a home in the Angular documentation. I downvoted your question b/c anything and everything relevant to your query is contained in the linked stackblitz. This is poor SO practice; in general do not depend on an external site's content to remain static and accessible. Links should be used sparingly and only to provide references. If the link must be followed to understand your question, you need to provide more information. I'll upvote if you revise. – acat Sep 18 '21 at 23:56
  • 1
    @acat I have solved the issue. I was giving the wrong name of the template. That's why it was not working in my own code –  Sep 21 '21 at 05:09
  • @SpaceBoi thanks for the clarity! and I messed up, I couldn't undo my downvote, SO is requiring the question to be edited before I am allowed to adjust my vote status. If it's important to you, just duplicate your comment in the question or even better, add the actual content of the link. Even if you solved it, for the sake of others who end up here after a quick google search – acat Sep 22 '21 at 03:37
  • @acat I have answered the question. Just upvote it or something –  Sep 22 '21 at 05:35
  • @SpaceBoi I'm telling you, when I try to upvote I get this message: "Your vote is now locked in unless this question is edited." just add a space or something – acat Sep 23 '21 at 22:37
  • @acat Done! Try to upvote again now –  Sep 24 '21 at 01:12
  • @SpaceBoi upvoted! apologies for the confusion – acat Sep 24 '21 at 01:41
  • Thanks alot @acat Hey would you mind, solving another problem of mine? I have been stuck with it for sometime –  Sep 24 '21 at 01:50
  • @SpaceBoi I can certainly try! is it up in another SO somewhere? – acat Sep 25 '21 at 18:26
  • @acat Its okay! I fixed that issue –  Sep 27 '21 at 13:55
  • @SpaceBoi just curious, what was the issue? and the solution? in case it's short enough to be SO-comment-length. and if not, if you're feeling altruistic, maybe want to create and self-answer an SO, just cuz others might be bound to have the same issue? no pressure though, just a suggestion! – acat Oct 01 '21 at 04:20
  • @acat I have a material-dialog. There is a template form in the form of table with dropdown. I want to prevent users from selecting the same option after it got selected. I am unable to solve it.(FYI,this is a different problem I am stuck at. Not what I asked for before. That was not needed. I neeed a solution for this one) –  Oct 01 '21 at 04:42
  • @SpaceBoi could you share a little more about the dropdown you're using? Is it your own component or a 3rd party? Although if I follow, my instinct tells me that you might want something like this: https://material.angular.io/components/select/overview#multiple-selection the dropdown items are checkboxes so you can only select something once. Is that what you're after? – acat Oct 02 '21 at 20:39
  • @acat https://stackoverflow.com/questions/69401777/angular-prevent-selection-of-same-options-from-a-dropdown/69402025?noredirect=1#comment122702140_69402025 This is the question –  Oct 03 '21 at 03:27

2 Answers2

1

From the provided code example, currentView refers to the value returned by the getter get currentView() {} here :

@Component({
  selector: 'editable',
  template: `
    <ng-container *ngTemplateOutlet="currentView"></ng-container>
  `
})
export class EditableComponent implements OnDestroy {
  @Output() update = new EventEmitter();
  @ContentChild(ViewModeDirective) viewModeTpl: ViewModeDirective;
  @ContentChild(EditModeDirective) editModeTpl: EditModeDirective;

  mode: 'view' | 'edit' = 'view';

  editMode = new Subject();
  editMode$ = this.editMode.asObservable();

  /***************
   *    HERE     *
   ***************/
  get currentView() {
    return this.mode === 'view' ? this.viewModeTpl.tpl : this.editModeTpl.tpl;
  }

Now, the error message probably means that this.viewModeTpl is undefined.

@ContentChild(ViewModeDirective) queries a ViewModeDirective which has [viewMode] as a selector. That is why it should target the <ng-template viewMode> element

As the code seems correct, I suspect a problem with the lifecycle. I suggest to change the code to something like this (only for debugging purpose, this piece of code is crap, but it will help to see if the problems comes from here):

  get currentView() {
    const template = this.mode === 'view' ? this.viewModeTpl : this.editModeTpl;
    return !!template ? template.tpl : undefined ;
  }
Arnaud Denoyelle
  • 29,980
  • 16
  • 92
  • 148
  • I tried that and this error is coming, `Type 'TemplateRef | undefined' is not assignable to type 'TemplateRef | null'. Type 'undefined' is not assignable to type 'TemplateRef | null'.ngtsc(2322) declare (property) NgTemplateOutlet.ngTemplateOutlet: TemplateRef | null A string defining the template reference and optionally the context object for the template.` –  Sep 14 '21 at 13:57
  • @SpaceBoi please try to define the template variables as optional, with an additional `?`, like this : `@ContentChild(ViewModeDirective) viewModeTpl?: ViewModeDirective;@ContentChild(EditModeDirective) editModeTpl?: EditModeDirective;` – Arnaud Denoyelle Sep 14 '21 at 14:00
  • I think I fixed that error. Now I am unable to view the values in the table. Do you have any other mean that we can talk? stackoverflow is very inconvenient to chat –  Sep 14 '21 at 14:15
  • From what I understand, `` is supposed to contain a <`ng-template viewMode>` and an `` that are queried respectively by `@ContentChild(ViewModeDirective) viewModeTpl` and `@ContentChild(ViewModeDirective) editModeTpl`. For a reason, `viewModeTpl` seems to be `undefined`. I would add some `console.log()` traces in `get currentView` in order to check if it is true. Also, I would double check that every `` contains at least a ``. Also, you could try to remove every `` ony by one in order to see which one is faulty. – Arnaud Denoyelle Sep 14 '21 at 14:29
  • You were right. I tried to console.log(viewModeTpl) and it showed undefined. Why is it so? @Arnaud –  Sep 14 '21 at 14:49
  • 1
    @SpaceBoi `@ContentChild(ViewModeDirective)` is trying to query a `ViewModeDirective` which has `[viewMode]` as a selector. That is why it should target `` and at this point, i have no idea about why it is not found. Did you try to remove every `` except one, to see if it works ? – Arnaud Denoyelle Sep 14 '21 at 14:56
  • 1
    OMG!!! I get where the error happened. The selector is different in my system. In that stackblitz project is was `[viewModel]`. In my personal project it was `[appViewModel]`. Thank You So Much my friend! –  Sep 14 '21 at 15:03
0

The error was the template name of the view and edit ng-template were wrongly referenced. That's why neither is able to locate the values