How can a parent's method be activated only after receiving an event emitter from the child and ensuring that the parent's ngIf condition is met?

Every time the element in the child template is clicked, it triggers the method activateService(name) and emits an event with the name of the selected service using the event emitter serviceSelected. The parent component's method scrollDown(name) is then called to set the attribute serviceActive to true and scroll down to the element with the id='service-view' in the parent's template. However, there is an issue where I have to click the child element twice for the scrolling effect to be triggered in the parent component. It seems like the scroll trigger happens before the element in the parent's template becomes visible. I'm unsure how to conditionally trigger the scroll functionality only after the value of activeService has been set to true, meaning after the parent element is visible. Does anyone have a solution to this problem?

Child:

.ts:

@Output('service') serviceSelected = new EventEmitter<string>();

activateService(service: string) {
   this.serviceSelected.next(service);
}

.html:

<div class="service" (click)="activateService('service1')">...</div>

Parent:

.ts:

serviceActive!: boolean;

scrollDown(evt: string) {
   this.onServiceActivated();
   document.getElementById("service-view")?.scrollIntoView({
      behavior: "smooth",
      block: "start",
      inline: "nearest"
   });
}

onServiceActivated() {
   this.serviceActive = true;
}

.html:

<app-services (service)="scrollDown($event)"></app-services>

<!--Display only if serviceActive is true-->
<div id="service-view" *ngIf="serviceActive">
   <app-services-detail></app-services-detail>
</div>

Answer №1

Have you given this a shot?

ancestor html:

<div id="service-view" *ngIf="serviceActive">
   <app-services-detail #serviceView></app-services-detail>
</div>

ancestor ts:

@ViewhChildren("serviceView") serviceViews:QueryList<ElementRef<HTMLelement>>;

   ...

scrollDown(evt: string) {

  this.onServiceActivated();

}
   ...

ngAfterViewInit () {

   this.serviceViews.changes.pipe(
     filter( list => !!list.first ),
     tap( list => {

       list.first.nativeElement.scrollIntoView({
        behavior: "smooth",
        block: "start",
        inline: "nearest"
       });

     } )
   ).subscribe();

 }

Answer №2

To implement the scrolling functionality, use the following code within a setTimeout function:

    scrollPage(direction: string) {
     this.activateService();
     setTimeoUT(()=>{
      document.getElementById("service-view")?.scrollIntoView({
      behavior: "smooth",
      block: "start",
      inline: "nearest"
      });
     })
   }

By adding this slight delay, ensure that all elements are rendered in the DOM before executing the scrolling action.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Combining Spring Boot and Angular applications for seamless integration

I am trying to connect my Spring Boot application with an Angular application that are running on different servers. When attempting to access REST API from the Angular app, the API call is successful but I encounter an error response on the UI. Acc ...

Issue encountered when using await in Tensorflow.js sample code with TypeScript

After going through the official tensorflow.js documentation, I attempted to test this example using typescript with tensorflow.js While trying to execute the code snippet provided in the tensorflow.js documentation, I encountered an error related to the ...

Angular 2: How to Avoid Exceeding Maximum Call Stack Size with Eager Loading

I'm facing an issue with preloading all of my child route modules. In my root routing module, I have the following configuration: RouterModule.forRoot(appRoutes, { preloadingStrategy: AppCustomPreloader }) The structure of AppCustomPreloader is as f ...

Add the file to the current directory

As a newer Angular developer, I am embarking on the task of creating a web page that enables users to upload files, with the intention of storing them in a specific folder within the working directory. The current location of the upload page component is ...

Eliminate incorrect or invalid state when resetting a dropdown in an Angular ng-select component

I have integrated the ng-select plugin into my Angular project for handling dropdowns. One specific requirement I have is to reset the second dropdown when the first dropdown is changed. Below is a snippet of the code: <ng-select [items]="branchMo ...

Linking typescript error messages with their respective compiler configurations (tsconfig.json)

Is there a way to identify which compiler option corresponds to a specific Typescript error? While working with Typescript in VSCode, I often encounter errors like initializer provides no value for this binding element. (Please note that these are warnin ...

Angular 5: Unable to add a destroyed View to a ViewContainer

I encountered a new error in my Angular application that I haven't seen before. The issue is arising from this specific line in the Angular source code. This error occurs when I log out and then log back into my app. While on a certain route, there i ...

Is the select all checkbox causing disabled checkboxes to be selected in an Angular environment?

<div *ngIf="showLog"> <!-- <p *ngIf="metricExecutionList Blockquote ===null">No Records Found</p> --> <div> <p-table #dt [value]="metricExecutionList" [l ...

What steps are required to transition an Angular application developed without the Angular CLI into an Angular CLI project?

I've created an Angular app using tools like NPM (without utilizing the Angular CLI). What would be the most efficient way to transition this project into the CLI project structure? I want to have the ability to utilize commands like ng serve. ...

The error message "Type 'null' cannot be assigned to type 'Element | DocumentFragment'" occurs when using Nextjs/React createPortal

I am completely new to typescript. Currently, I'm working on a project that has a lot of pre-configured react components in JavaScript files (.js). My task now is to convert everything to TypeScript (.tsx) without triggering any ESLint errors. Unfort ...

The OnPrepareResponse method in StaticFileOptions does not trigger when serving the index.html file

Currently, I am attempting to disable caching for index.html in my Angular SPA that is connected to a .NET Core 2.2 backend. I am following the instructions provided in this particular answer by implementing an OnPrepareResponse action for my StaticFileOp ...

Ways to define an interface that can accommodate various interfaces with a specific structure

I am in need of a function that can accept a parameter with interfaces having a specific structure. The parameter should be either a string hash or a string hash along with an attribute string hash, as shown below: { anotherHash: { a: 'a', ...

Angular Bootstrap: How to Resolve the Error "Function $(...).collapse() is Undefined"

I'm a beginner with Bootstrap and I'm attempting to trigger the .collapse() function using JavaScript within an Angular controller when a user clicks on a link. The goal is to close the collapsible navbar when a link is clicked, as the routing in ...

Discovering new bugs in VSCode Playwright Tests but failing to see any progress

This morning, everything was running smoothly with debugging tests. However, after a forced reboot, I encountered an issue where it seems like the debugger is running, but nothing actually happens. This has happened before, but usually resolves itself. Unf ...

The RxJs Observer connected to a websocket only triggers for a single subscriber

Currently, I am encapsulating a websocket within an RxJS observable in the following manner: this.wsObserver = Observable.create(observer=>{ this.websocket.onmessage = (evt) => { console.info("ws.onmessage: " + evt); ...

How can one click the button within the expanded dropdown while hovering over the navigation item in Angular and Bootstrap?

Issue Description: Upon hovering over a navigation item, the dropdown container is displayed but it's not clickable. Desired Behavior: Hovering over a navigation item should display the dropdown container and allow clicking on its contents. Furthermo ...

"I am looking for a way to incorporate animation into my Angular application when the data changes. Specifically, I am interested in adding animation effects to

Whenever I click on the left or right button, the data should come with animation. However, it did not work for me. I tried adding some void animation in Angular and placed a trigger on my HTML element. The animation worked when the page was refreshed, bu ...

The proper method for retrieving FormData using SyntheticEvent

I recently implemented a solution to submit form data using React forms with the onSubmit event handler. I passed the SyntheticBaseEvent object to a function called handleSubmit where I manually extracted its values. I have identified the specific data I n ...

Remix.js is unable to perform a redirect action when utilizing the Form component

I've been searching through the Remix documentation, but I can't seem to find a solution to my issue. It appears that you're unable to redirect from an action when using the Form component in Remix. You can check out this StackBlitz example ...

What determines the narrowing of a type when it is defined as a literal versus when it is returned from a function?

I'm really trying to wrap my head around why type narrowing isn't working in this scenario. Here's an example where name is successfully narrowed down: function getPath(name: string | null): "continue" | "halt" { if (n ...