Ao desenvolver aplicações que utilizam redes de anúncios ou scripts externos (como Adsterra, AdSense ou widgets de terceiros), é comum enfrentarmos dois desafios: o bloqueio por antivírus/adblocks durante demonstrações profissionais (como em processos seletivos) e erros de execução no ciclo de vida do Angular quando tentamos esconder esses elementos.

Neste artigo, exploraremos como criar um serviço de injeção dinâmica e como tratar o erro TypeError: Cannot read properties of undefined (reading 'nativeElement').

1. O Problema: Manipulação de Elementos Inexistentes Link para o cabeçalho

O erro ocorre quando usamos o @ViewChild para capturar uma referência do HTML e tentamos acessá-la no ngAfterViewInit. Se o elemento estiver dentro de um *ngIf que resultou em falso, a referência será undefined`, e tentar ler sua propriedade nativeElement quebrará a aplicação.


2. A Solução: Serviço de Injeção Dinâmica com Environment` Link para o cabeçalho

Em vez de poluir o index.html, centralizamos a lógica em um serviço que respeita as variáveis de ambiente da aplicação.

O Serviço de Ads:

@Injectable({ providedIn: 'root' })
export class AdsService {
  // Controle centralizado via environment
  private readonly podeExibir = environment.exibirAnuncios; 

  constructor(@Inject(PLATFORM_ID) private platformId: Object) {}

  init() {
    if (isPlatformBrowser(this.platformId) && this.podeExibir) {
      this.injetarScripts();
    }
  }

  private injetarScripts() {
    const scripts = ['https://link-do-anuncio.js'];
    scripts.forEach(src => {
      const script = document.createElement('script');
      script.src = src;
      script.async = true;
      document.body.appendChild(script);
    });
  }
}

3. Tratamento Seguro no Componente Link para o cabeçalho

Para evitar que o log do console fique “vermelho” quando os anúncios estão desativados, precisamos de uma checagem defensiva antes de manipular o DOM.

O Componente de Exibição:

@Component({ ... })
export class AdContainerComponent implements AfterViewInit {
  @ViewChild('adContainer') adContainer!: ElementRef;
  
  readonly adsAtivos = environment.exibirAnuncios;

  ngAfterViewInit() {
    // Checagem dupla: O ambiente permite E o elemento foi renderizado?
    if (this.adsAtivos && this.adContainer) {
      this.renderizarWidget();
    }
  }

  private renderizarWidget() {
    const el = this.adContainer.nativeElement;
    if (el) {
      // Lógica específica do script externo
    }
  }
}

Conclusão Link para o cabeçalho

Essa abordagem traz três grandes benefícios:

  1. Clean Code: O componente não se preocupa com a carga do script, apenas com o espaço em tela.

  2. Segurança: Evita que antivírus acusem seu site como malicioso durante uma apresentação de portfólio, bastando setar a flag como false.

  3. Robustez: O uso de checagens defensivas no ngAfterViewInit garante que a aplicação não pare de funcionar por erros de referência nula.