IonViewDidEnter called twice on startup

I was wondering if you could me with this task. I have tried a few suggestions from similar threads I’ve found and tried some I could easily detect, but I couldn’t really relate others to my situation, so perhaps you can help me in my particular case.

The issue here is that the ionViewDidEnter hook is triggered twice once the app is launched (however, it doesn’t do that afterwards, for example, if you navigate to other pages and come back, it will correctly only trigger once). I’ll put the html and ts code here so for more clarity. If more info is needed, please let me know! Cheers everyone

HTML:

<ion-header>
  <ion-toolbar>
    <ion-title>Join an Event</ion-title>
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>
      
 
<ion-content>
  <div padding text-center *ngIf="!hasVerifiedEmail">
    Please verify your email to view the events!
    <ion-button (click)="sendVerificationEmail()">Send verification email</ion-button><br>
    Click refresh if you have verified!
    <ion-button (click)="pageReload()">Refresh</ion-button>
  </div>
  
<div *ngIf="hasVerifiedEmail">

  <ion-searchbar mode="ios"  placeholder="Search Event by Name" show-clear-button="always" showCancelButton="focus" (ionChange)="searchField($event)"></ion-searchbar> <!--  (ionCancel)="getUserPrefs()" -->

  <h6>Filter Events by Sport/Activity</h6>
  <ion-slides class="categories-slides" [options]="catSlideOptions">
    <ion-slide (click)="changeSportPreference('All')"><img src="assets/img/cat-all.jpg"></ion-slide>
    <ion-slide (click)="changeSportPreference('Soccer')"><img src="assets/img/cat-soccer.jpg"></ion-slide>
    <ion-slide (click)="changeSportPreference('Basketball')"><img src="assets/img/cat-basketball.jpg"></ion-slide>
    <ion-slide (click)="changeSportPreference('Tennis')"><img src="assets/img/cat-tennis.jpg"></ion-slide>
    <ion-slide (click)="changeSportPreference('Gym')"><img src="assets/img/cat-gym.jpg"></ion-slide>
    <ion-slide (click)="changeSportPreference('Running')"><img src="assets/img/cat-running.jpg"></ion-slide>
  </ion-slides>

  <h6>Find a Place (Coming Soon!)</h6>
  <ion-slides [options]="placesOptions">

    <ion-slide>
      <ion-card><img src="assets/img/pitch-smithfield.jpg">
        <ion-card-header>
          <ion-card-title>Smithfield Astro Pitch</ion-card-title>
          <ion-button small expand="block" fill="outline" (click)="comingSoonAlert()"><ion-card-subtitle>Book Now</ion-card-subtitle></ion-button>
      </ion-card-header>
      </ion-card>
    </ion-slide>

    <ion-slide>
      <ion-card><img src="assets/img/pitch-example.jpg">
        <ion-card-header>
          <ion-card-title>Example Astro Pitch</ion-card-title>
          <ion-button small expand="block" fill="outline" (click)="comingSoonAlert()"><ion-card-subtitle>Book Now</ion-card-subtitle></ion-button>
      </ion-card-header>
      </ion-card>
    </ion-slide>

  </ion-slides>

  <ion-button small expand="block" fill="outline" (click)="toggleFilteredEvents()"><ion-card-subtitle>{{ showFilteredEvents ? "Show All Events" : "Show Events Within 5km" }}</ion-card-subtitle></ion-button>

  
  <!-- Modified this for Pagination test 2, copy code from repo to backup -->
  <ion-list *ngIf="itemsPage!==undefined">
    <h6>Events Available</h6>
     <ion-card *ngFor="let evt of (showFilteredEvents ? eventsWithin5Km : itemsPage)" padding style="background: url('../../../assets/img/gameon-tennis-bg.jpg') no-repeat center center / cover;"> 
      <ion-row>
        <ion-col>
          <ion-card-subtitle>{{ evt.date | date:'dd/MM/yyyy' }}, at {{ evt.date | date:'h:mm a'}}</ion-card-subtitle>
          <ion-card-title>{{ evt.type }}</ion-card-title>
          <ion-card-subtitle>{{ evt.title }}</ion-card-subtitle>
          <ion-card-subtitle><ion-icon name="pin"></ion-icon>{{ evt.location }}</ion-card-subtitle>
          <ion-card-subtitle>Participants: <span class="numPart"> {{ evt.part.length }}</span> / <span class="numPlayers">{{ evt.players }}</span></ion-card-subtitle>
        </ion-col>
        <ion-col>
          <ion-button small expand="block" fill="outline" (click)="viewEventDetails(evt)">View Event</ion-button>
          <!-- <ion-button small expand="block" fill="outline" (click)="addMeToEvent(evt)">Join Event</ion-button> -->
          <ion-button small expand="block" fill="outline" (click)="joinEvent(evt)">Join Event</ion-button>
        </ion-col>
      </ion-row>
     </ion-card>
  </ion-list>

  <div *ngIf="itemsPage?.length<=0" class="ion-padding">
    <ion-item class="ion-text-center txtAlert" lines="none">
      No events available for this category
    </ion-item>
    <ion-item class="ion-text-center txtAlert" lines="none">
     <ion-label><ion-button small expand="block" fill="outline" (click)="userCurrentPreferredSport('All')">View All</ion-button> or <ion-button small expand="block" fill="outline" (click)="createEvent()">Create one!</ion-button></ion-label>
    </ion-item>
  </div>
  

  <ion-infinite-scroll threshold="80px" (ionInfinite)="loadDataInfiniteScrolling($event)">
    <ion-infinite-scroll-content
      loadingSpinner="bubbles" 
      loadingText="Loading more data...">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>

</div>
</ion-content>

TS:

constructor(
    private eventServ: EventsService,
    private alertServ: AlertService,
    private userServ: UsersService,
    private pushServ: PushService,
    private authServ: AuthService,
    public loadServ: LoadService,
    private router: Router,
    private locationAccuracy: LocationAccuracy, // GPS and Geolocation for User and Events
    private actRoute: ActivatedRoute // GPS and Geolocation for User and Events
  ){
    
  }

  ngOnInit() {
    
  }


  async ionViewDidEnter() {
    console.log('ionViewDidEnter() called');
    
    this.loadServ.presentLoad();
    
    this.events = []
    this.currentUser = JSON.parse(localStorage.getItem('currentUser') || '{}');

    this.getUserProfile();
    this.userModel = {};
    this.getCurrentLocation();

    // ADDED TO ATTEMPT TO TRY TO CALCULATE USERS AND EVENT DISTANCE
    this.eventLocation = this.actRoute.snapshot.paramMap.get('eventLocation');
    this.userLocation = null;

    console.log("the user has verified his email.");

  }

  getUserProfile() {
    this.userServ.getUserProfile(this.currentUser['user']['uid']).then((doc: any) => {
      if (doc.exists) {
        this.user = this.currentUser;
        this.tempUser = doc.data();
        this.userModel = this.tempUser;
        this.userName = this.userModel.name ?? " ";
        this.userFavSport = this.userModel.pref ?? 'all';
      } else {
        console.log("getUserProfile failed");
      }
      this.listEvents(this.userFavSport);
    });
  }

  // Setting and changing the User's preferred Sport
  userCurrentPreferredSport(userFavSport?: any) {
    this.index = 0;
    let localPref: any;
    console.log('PrefArray:', userFavSport);
  
    if (userFavSport !== undefined) {
      localPref = userFavSport;
    } else if (this.userFavSport !== undefined) {
      localPref = this.userFavSport;
    } else {
      localPref = 'All';
    }
    console.log('localPref:', localPref); // debugging
  
    if (localPref == 'All') {
      // Load all events when "All" is selected
      // Filter to include all data types
      this.itemsPage = this.events.slice(this.index, this.index + this.offset);
      this.index += this.offset;
    } else {
      let prefItemsPage = this.events.filter((item: any) => {
        if (localPref == 'All') {
          // Include all data types when localPref is "All"
          return true;
        } else {
          return item.type === localPref;
        }
      });
      console.log('prefItemsPage:', prefItemsPage); // debugging
  
      // Load the initial set of events based on user preference
      this.itemsPage = prefItemsPage.slice(this.index, this.index + this.offset);
      this.index += this.offset;
    }
  
    // Check if there are more events to load
    this.checkIndexToLoad();
    
  }

  changeSportPreference(selectedSport: string) {
    this.userFavSport = selectedSport; // Update the user's sport preference
    this.userCurrentPreferredSport(this.userFavSport); // Call the preference function to load events of the selected sport
  }

  // Infinite Scrolling
  async checkIndexToLoad() {
    if (this.index < this.events.length) {
      // Enable infinite scrolling if there are more events to load
      this.infiniteScroll!.disabled = false;
    } else {
      // Disable infinite scrolling if no more events are available
      this.infiniteScroll!.disabled = true;
    }
  }

  scrollHandler(e:any) {
    console.log("e: ", e);
    if (e === 'bottom') {
      //this.page.more()
    }
  }

  async loadDataInfiniteScrolling(event: any) {
    this.reActiveInfinite = event;
  
    console.log('loadData called. userFavSport: ', this.userFavSport);
  
    setTimeout(() => {
      // Load more events based on the user's current sport preference
      let filteredEvents = [];
  
      if (this.userFavSport === 'All') {
        // Load more events without sport type filtering when 'All' is selected
        filteredEvents = this.events;
      } else {
        // Load more events based on the user's current sport preference
        filteredEvents = this.events.filter((event: any) => {
          return event.type === this.userFavSport;
        });
      }
  
      const moreEvents = filteredEvents.slice(this.index, this.index + this.offset);
  
      this.index += this.offset;
  
      for (let i = 0; i < moreEvents.length; i++) {
        this.itemsPage.push(moreEvents[i]);
      }
  
      event.target.complete();
  
      // Check if there are more events to load
      this.checkIndexToLoad();
    }, 1000);
  }

  // Page reload after user verifies email
  pageReload(){
    window.location.reload();
  }

  // Search Field (top bar)
  async searchField(event: any) {    
    this.itemsPage = await this.eventServ.initializeEvents();
    const searchTerm = event.srcElement.value;

    if (!searchTerm) { 
        return;
    }

    this.itemsPage = this.itemsPage.filter((currentEvent: any) => {
        return (
            currentEvent.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
            currentEvent.type.toLowerCase().includes(searchTerm.toLowerCase())
        );
    });
}


  // Events-related functions (List, View, Create, Join)
  async listEvents(pref: any){
    this.eventServ.listEvents().subscribe(async (res: any[])=>{

      this.events = res.map(e => {
        
        return {
          id: e.payload.doc.id,
          createdAt: e.payload.doc.data()['createdAt'],
          createdBy: e.payload.doc.data()['createdBy'],
          part: e.payload.doc.data()['part'],
          comments: e.payload.doc.data()['comments'],
          type: e.payload.doc.data()['type'],
          title: e.payload.doc.data()['title'],
          date: e.payload.doc.data()['date'],
          time: e.payload.doc.data()['time'],
          map: e.payload.doc.data()['map'],
          players: e.payload.doc.data()['players'],
          location: e.payload.doc.data()['location'],
          description: e.payload.doc.data()['description'],
          image: e.payload.doc.data()['image'],
        } as Event;        
      }) 
      
      console.log('Events => ', this.events);
      if(this.events.length>0){
        this.userCurrentPreferredSport(pref);

      }
    });
    
    setTimeout(() => {

      this.loadServ.dismissLoad();
    }, 1000);
  }

  viewEventDetails(evt:any){
    this.router.navigate(['/event', { dataEvt: JSON.stringify(evt) }]);
  }

  createEvent(){
    this.router.navigate(['/create-event']);
  }

  joinEvent(evt: any){
    let evTopic = evt.id;
    FCM.subscribeTo({ topic: evTopic });
    let myUID = this.currentUser['user']['uid'];

    evt['part'].forEach((element: { [x: string]: any; }) => {
        if (JSON.stringify(evt['part'].length) == evt['players']) {
        this.eventIsFull = true;
      }
      else if (element['id'] == myUID || this.currentUser.isAdmin){
        this.alreadyInEvent = true;
      }
      else {
        this.alreadyInEvent = false;
      }
      console.log('evt[part]: ', element); 
    });

    if(this.alreadyInEvent == false && this.eventIsFull == false){
      let addUser = {
        'id': myUID,
        'name': this.userName,
        'isAdmin': false
      }
      evt['part'].push(addUser);
      this.updateProfile(evt['id']);
      let msg = 'Joined Event successfuly!';
      this.alertServ.myAlert(msg);
      this.eventServ.joinEvents(evt.id, evt).then((res:any)=>{
        let myName = this.userName; 
        let msg = myName + ' joined the event';
        this.pushServ.sendPush(evTopic, myName, msg).subscribe((res:any)=> {
          console.log("Res push: ", res)
        })
        
      this.viewEventDetails(evt);
      });
    }else if (this.alreadyInEvent == true){
      let msg = 'You are already in this event!';
      this.alertServ.myAlert(msg);
    } else if (this.eventIsFull == true && this.alreadyInEvent == false) {
      let msg = 'This event is full!';
      this.alertServ.myAlert(msg);
    }
  }

  updateProfile(evtID:any) {
    let uid = this.currentUser['user']['uid'];
    console.log('evtID-1: ', evtID);
    if(evtID!==undefined){
      if(this.userModel['myevt']==undefined){
        this.userModel['myevt'] = [evtID];
      }else{
        this.userModel['myevt'].push(evtID);
      }
      console.log('this.model: ', this.userModel);
      this.authServ.updateProfile(uid, this.userModel)
        .then(res => {
          console.log('Update User Evt', res);
      });
    }else{
      console.log('evtID-3: ', evtID);
    }
  }

  // GPS and Geolocation for User and Events
  async getCurrentLocation() {
    try {
      const permissionStatus = await Geolocation.checkPermissions();
      console.log('Permission status: ', permissionStatus.location);
      if(permissionStatus?.location != 'granted') {
        const requestStatus = await Geolocation.requestPermissions();
        if(requestStatus.location != 'granted') {
          // go to location settings
          await this.openSettings(true);
          return;
        }
      }

      if(Capacitor.getPlatform() == 'android') {
        this.enableGps();
      }

      let options: PositionOptions = {
        maximumAge: 3000,
        timeout: 10000,
        enableHighAccuracy: true
      };
      const position = await Geolocation.getCurrentPosition(options);
      console.log(position);
      console.log("Latitude: ", position.coords.latitude);
      console.log("Longitude: ", position.coords.longitude);
      this.userLocation = {
        lat: position.coords.latitude,
        lng: position.coords.longitude,
      };
    } catch(e: any) {
      if(e?.message == 'Location services are not enabled') {
        await this.openSettings();
      }
      console.log(e);
    }
  }

  // Open Settings on phone for the purpose of granting location permission from the user
  openSettings(app = false) {
    console.log('open settings...');
    return NativeSettings.open({
      optionAndroid: app ? AndroidSettings.ApplicationDetails : AndroidSettings.Location, 
      optionIOS: app ? IOSSettings.App : IOSSettings.LocationServices
    });
  }

  async enableGps() {
    const canRequest = await this.locationAccuracy.canRequest();
    if(canRequest) {
      await this.locationAccuracy.request(this.locationAccuracy.REQUEST_PRIORITY_HIGH_ACCURACY);
    }
  }

  filterEventsWithin5Km() {
    const R = 6371; // Radius of the Earth in kilometers
  
    this.eventsWithin5Km = this.events.filter((event:any) => {
      // Ensure event.map is not null or undefined before accessing its properties
      if (event.map?.lat && event.map?.lng && this.userLocation?.lat && this.userLocation?.lng) {
        // Parse the latitude and longitude values
        const eventLat = parseFloat(event.map.lat);
        const eventLng = parseFloat(event.map.lng);
        const userLat = parseFloat(this.userLocation.lat);
        const userLng = parseFloat(this.userLocation.lng);
  
        // Calculate the distance
        const dLat = (eventLat - userLat) * (Math.PI / 180);
        const dLon = (eventLng - userLng) * (Math.PI / 180);
        const a =
          Math.sin(dLat / 2) * Math.sin(dLat / 2) +
          Math.cos(userLat * (Math.PI / 180)) * Math.cos(eventLat * (Math.PI / 180)) *
          Math.sin(dLon / 2) * Math.sin(dLon / 2);
        const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        const distance = R * c; // Distance in kilometers
  
        console.log('Event:', event.title);
        console.log('Event Location:', eventLat, eventLng);
        console.log('User Location:', userLat, userLng);
        console.log('Distance:', distance);
  
        return distance <= 5; // Return true for events within 5 km
      } else {
        return false; // If event.map or userLocation is null or undefined, return false
      }
    });
  
    console.log('Filtered Events:', this.eventsWithin5Km);
  }
  

  toggleFilteredEvents() {
    this.showFilteredEvents = !this.showFilteredEvents;
  
    if (this.showFilteredEvents) {
      // If showing filtered events, call the filtering function
      this.filterEventsWithin5Km();
    }
  }

  // Alerts
  comingSoonAlert(){
    let msg = 'This feature is not yet available! Check back later!';
      this.alertServ.myAlert(msg);
  }

  // User Logout
  logout() {
    this.authServ.logout().then(() => {
      this.router.navigate(['/login']);
    })
  }

}

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật