0

So I am creating a simple fill in the blanks app and I have identifiers in the string that I want to replace with the select box.

Typescript

const string = `##blank.0## is the capital city of China. It's most famous attraction is## blank .1##.`;

ngOnInit() {
  this.answers.forEach(a => {
    this.string = this.sanitizer.bypassSecurityTrustHtml(this.string.replace(`##blank.${a.index}##`,
      `<select class="select-boxes">
      <option *ngFor="let answer of ${a.answers}" [value]="answer.id">
        {{ answer.content }}
      </option>
    </select> `));
  });
}

HTML

<p [innerHTML]="string"></p>

Problem

It renders the select box but neither the styles nor the *ngFor list.

Any help would be greatly appreciated.

SiddAjmera
  • 38,129
  • 5
  • 72
  • 110
Kissa Eric
  • 77
  • 1
  • 11

1 Answers1

1

Following my previous (& deleted) answer, you reuqested an example of dynamic rendering.

I have made a stackblitz as per the one you have provided :

https://stackblitz.com/edit/my-angular-starter-xelsuj?file=app/app.component.ts

In this stackblitz, you will see that the content is dynamic, but still in the Angular context. Thanks to that, you can still use the Angular directives, and you don't rely on innerHTML anymore.

export class AppComponent {
  content: SafeHtml;
  str = `##blank.0## is the capital city of China, ##blank.1## is the capital of France.`;
  answers = [{
    ref: 0,
    answers: [
      { id: 0, content: 'Beijing' },
      { id: 1, content: 'Shanghai' },
      { id: 2, content: 'Ghuangzhou' },
      { id: 3, content: 'The Great wall' },
    ],
    bit: undefined,
  }, {
    ref: 1,
    answers: [
      { id: 0, content: 'Stockholm' },
      { id: 1, content: 'New York' },
      { id: 2, content: 'Malibu' },
      { id: 3, content: 'Paris' },
    ],
    bit: undefined,
  }];


  constructor(sanitizer: DomSanitizer) {
    // Split the string into bits
    let bits = this.str.split(/##blank\.\d+##/);
    // remove empty bits (mostly start & end)
    bits = bits.filter(bit => !!bit);
    // Add the bit to the answer
    this.answers = this.answers.map((answer, index) => ({
      ...answer,
      bit: bits[index],
    }));
  }
}