After being initialized, Ionic 3 Tabs do not properly refresh

Every time a tab is clicked, the Component "EventDetailItemsComponent" is called with different navParams. The async data (Observable) is fetched from this.itemService and displayed as expected.

The issue arises when switching back to the same tab for the second time. Since the Component is not recalled, it displays the same async data. Therefore, the tab view is not updated.

I aim to invoke EventDetailItemsComponent every time a tab is clicked, not just on the initial click.

Would it be correct to transmit the async data from the parent component EventDetailComponent to the child component EventDetailItemsComponent using (ionSelect)="myMethod()"

    <ion-tabs no-margin no-padding selectedIndex="1">
        <ion-tab [root]="EventDetailItems1" [rootParams]="{itemTypeId:1, eventId: (eventDetail | async)?.id}" tabTitle="{{'ALL' | translate}}"></ion-tab>
        <ion-tab [root]="EventDetailItems2" [rootParams]="{itemTypeId:2, eventId: (eventDetail | async)?.id}" tabTitle="{{'BOUGHT' | translate}}"></ion-tab>
        <ion-tab [root]="EventDetailItems3" [rootParams]="{itemTypeId:3, eventId: (eventDetail | async)?.id}" tabTitle="{{'LEFT' | translate}}"></ion-tab>
    </ion-tabs>


    export class EventDetailComponent implements OnInit {

        EventDetailItems1: any = EventDetailItemsComponent;
        EventDetailItems2: any = EventDetailItemsComponent;
        EventDetailItems3: any = EventDetailItemsComponent;

        constructor(){ }
    }

Child Component EventDetailItemsComponent and its html

    @Component({
        selector: 'event-detail-items',
        styleUrls: ['/event-detail-items.scss'],
        templateUrl: 'event-detail-items.html'
    })
    export class EventDetailItemsComponent implements OnInit, OnChanges  {
        private _itemDetail = new BehaviorSubject<ItemViewModel[]>(null);
        itemDetail = this._itemDetail.asObservable();

        itemToggle: number = 0;
        lastImage: string = null;
        loading: Loading;

        constructor(
            public itemService: ItemService,
            public eventService: EventService,
            public navParams: NavParams,
            public navCtrl: NavController,
            public loadingCtrl: LoadingController,
            private app: App) {

        }

        ngOnInit() {
            let itemParams: GiftItemTabNavParams = JSON.parse(JSON.stringify(this.navParams.data));                
            this.itemService.getItemList(itemParams.eventId, itemParams.itemTypeId).subscribe(x => {
                this._itemDetail.next(x);
            });
        }
    }


          <ion-grid id="gift-list-grid">                
            <ion-row class="gift-list-row" *ngFor="let giftItem of (itemDetail | async)" text-center bottom>
                <ion-col (click)="toggleItemDescription(giftItem.id)" class="gift-item-col-item-pic" col-3>
                    <img src="{{giftItem.giftImagePath}}" />
                </ion-col>
                <ion-col (click)="toggleItemDescription(giftItem.id)" class="gift-item-col-detail" col-6>
                    <ion-label text-wrap class="gift-item-text" no-margin text-left>
                        <span>
                            {{giftItem.giftItemName}}
                        </span>
                        <span>
                            {{giftItem.brand}}
                        </span>
                    </ion-label>
                </ion-col>
                <ion-col (click)="toggleItemDescription(giftItem.id)" class="gift-item-col-gift-count" col-3>
                    <img src="./assets/img/inner-pages/gift_box.png" />
                    <p>
                        {{giftItem.amount}}
                    </p>
                </ion-col>
                <ion-col (click)="toggleItemDescription(giftItem.id)" *ngIf="itemToggle == giftItem.id" col-9>
                    <ion-label text-wrap class="gift-item-description" no-margin text-left>
                        <span>
                            {{giftItem.amount}} {{'AMOUNT' | translate}}
                        </span>
                        <span>
                            {{giftItem.description}}
                        </span>
                    </ion-label>
                </ion-col>
                <ion-col (click)="toggleBuyStatus(giftItem.id, giftItem.isBought, giftItem.giftStatus)" *ngIf="itemToggle == giftItem.id" class="gift-item-col-detail"  col-3>
                    <!--RESERVABLE ITEM-->
                    <img *ngIf="giftItem.giftStatus == 0" src="./assets/img/inner-pages/free.png" />
                    <!--CAN BE UNRESERVED-->
                    <img *ngIf="giftItem.giftStatus == 1" src="./assets/img/inner-pages/unreservable.png" />
                    <!--CAN NOT BE UNRESERVED-->
                    <img *ngIf="giftItem.giftStatus == 2" src="./assets/img/inner-pages/not-unreservable.png" />
                </ion-col>
            </ion-row>
        </ion-grid>

UPDATE: According to Sampath's suggestion, Events resolved the issue. Here is how it was used:

Root EventDetailComponent - Event Publish:

public eventTabsChanged(itemTypeId) {
            let event = this._eventDetail.getValue();
            this.events.publish('tab:clicked', itemTypeId, event.id);
        }

Tab content EventDetailItemsComponent - Event Subscribe

    constructor(
            public itemService: ItemService,       
            public events: Events) {
            events.subscribe('tab:clicked', (itemTypeId, eventId) => {
                this.itemService.getItemList(eventId, itemTypeId).subscribe(x => {
                    this._itemDetail.next(x);
                });
            });
        }

Answer №1

If you're looking to transfer information from a parent component to a child component, one way to achieve this is by using input properties.

Here's an example:

For your specific scenario:

<event-detail-items [itemDetail]="itemDetail"></event-detail-items>

You can refer to the official documentation here for more information.

In the child component file (child.ts):

import { Component, Input } from '@angular/core';

import { Hero } from './hero';

@Component({
  selector: 'hero-child',
  template: `
    <h3>{{hero.name}} says:</h3>
    <p>I, {{hero.name}}, am at your service, {{masterName}}.</p>
  `
})
export class HeroChildComponent {
  @Input() hero: Hero;
  @Input('master') masterName: string;
}

In the parent component file (parent.ts):

import { Component } from '@angular/core';

import { HEROES } from './hero';

@Component({
  selector: 'hero-parent',
  template: `
    <h2>{{master}} controls {{heroes.length}} heroes</h2>
    <hero-child *ngFor="let hero of heroes"
      [hero]="hero"
      [master]="master">
    </hero-child>
  `
})
export class HeroParentComponent {
  heroes = HEROES;
  master = 'Master';
}

Another approach: You can also utilize Events for communication between components.

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

Stop webpack from stripping out the crypto module in the nodejs API

Working on a node-js API within an nx workspace, I encountered a challenge with using the core crypto node-js module. It seems like webpack might be stripping it out. The code snippet causing the issue is: crypto.getRandomValues(new Uint32Array(1))[0].toS ...

What is the best way to transfer information between two components when working with an edit form?

Presently, I am utilizing a modal material dialog window that prompts the user to input a number and then press search. Upon searching, it retrieves data from an API call and receives a response object. My goal is to utilize this response object to populat ...

Common Mistakes when Using Angular 4 Dropdowns

I attempted to implement the Angular 4 Drop Down feature: https://www.npmjs.com/package/ng4-material-dropdown Below is the code snippet for my div element setup: <ng4-dropdown> <ng4-dropdown-menu> <ng4-menu-item *ngFor="let item of ...

Angular update encountering errors due to a mistakenly "resolved" address

Good morning everyone, I am currently in the process of upgrading Angular from version 7.1.0 to 8.3.23. We have a customized package stored on our DevOps server. I can successfully fetch the package using npm by deleting the directory and running 'n ...

Encountered an issue with updating geolocation values: unable to read property 'setState' due to its undefined state

While attempting to obtain latitude and longitude through geolocation, I successfully obtained the values. However, when I attempted to set state values, I encountered an error stating "Cannot read property 'setState' of undefined." This error li ...

Transform my Angular implementation to TypeScript programming

After spending a year coding Angular and seeing great progress, the buzz around TypeScript has caught my attention. While there are plenty of tutorials and blogs on the topic, there seems to be inconsistency in the recommendations. How should the app.js fi ...

Exploring intricate JSON data in Angular 4 applications

Below is the json structure I have: [ { "section":{ "secName":"Module 1", "pages":[ { "pageName":"Page 1", "pageType":"brightcove", "pageData":[ { ...

In what way can TypeScript, a classless object-oriented programming language, support the implementation of static methods?

I'm finding myself in a bit of a dilemma. How is it possible for TypeScript to have static methods if it transpiles to JavaScript, which is known as a classless language? From my understanding, in object-oriented programming languages that support cl ...

The toISOString() method is deducting a day from the specified value

One date format in question is as follows: Tue Oct 20 2020 00:00:00 GMT+0100 (Central European Standard Time) After using the method myValue.toISOString();, the resulting date is: 2020-10-19T23:00:00.000Z This output shows a subtraction of one day from ...

Unable to successfully remove item using Asyncstorage

const deleteProduct = prod => { Alert.alert( 'Delete Product', `Are you sure you want to remove ${prod.id}?`, [ { text: 'Cancel', style: 'cancel', }, { ...

Retrieval and sorting of documents by their unique identifiers

There are approximately 20 documents stored in the Firebase database, each containing fields with unique "id" values. How can we filter the database query to only retrieve documents with a specific "id" and exclude all others? ...

Incorporating a bootstrap design template into an angular application by utilizing angular components

As someone who is not a front-end developer and is starting to build a web app from scratch, I decided to download a bootstrap template and integrate it into a simple Angular project (generated by Angular CLI). Here's what I did: I copied the inde ...

Access the Angular application directly from the email

Our infrastructure consists of a .NET back-end, an Angular 5 application, and a nginx server. Upon registering your account in the application, you will receive an email with a verification link structured as follows: [root]/register/verify?userId=blabla& ...

Grid display not showing scheduled events

I am encountering an issue with fullcalendar in my project where it is not showing the events within the day grid. Despite attempting to adjust the timezone and experimenting with different combinations of times and dates, the problem persists. // Html ...

Angular is able to select an element from a specified array

I'm currently struggling with using Angular to manipulate a TMDB API. I am having difficulty retrieving an item from an array. Can someone provide assistance? Here is the response that the array returns: { "id": 423108, "results ...

Modifying the version target of TypeScript code results in the TypeScript Compiler being unable to locate the module

After installing signalr via npm in Visual Studio 2019, I encountered an issue. When the target in my compiler options is set to ES6, I receive the error TS2307 (TS) Cannot find module '@microsoft/signalr.'. However, when I change the target to E ...

Issue with event.stopPropagation() in Angular 6 directive when using a template-driven form that already takes event.data

I am currently developing a citizenNumber component for use in forms. This component implements ControlValueAccessor to work with ngModel. export class CitizenNumberComponent implements ControlValueAccessor { private _value: string; @Input() place ...

Angular - Resolving the issue of 'property does not exist on type' in TypeScript

Currently, I am following a video tutorial which also has a text version. Despite copying the code exactly as shown in the tutorial, I encountered the following error: Error TS2339: Property 'getEmployees' does not exist on type 'Employ ...

Manage and execute a sequence of multiple actions with Redux-Observable

Utilizing redux-observable, my goal is to generate multiple WORK actions from a single epic. Here's what I have so far: ( action$, state$ ) => { return action$.pipe( ofType( 'SPAWN' ), flatMap( action => { retu ...

Receiving information within an Angular Component (Profile page)

I am currently developing a MEAN Stack application and have successfully implemented authentication and authorization using jWt. Everything is working smoothly, but I am encountering an issue with retrieving user data in the Profile page component. Here ar ...