no me esta llegando los params a mi construtor this si code import { Component, OnInit, ViewChild, OnDestroy, inject, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import { CommonModule } from '@angular/common';import { FormsModule } from '@angular/forms';import {IonContent,IonHeader,IonTitle,IonToolbar,IonButtons, IonBackButton,IonInput, IonButton, IonIcon, IonSpinner, IonFooter, } from "@ionic/angular/standalone" import { ConversationService } from '@services/conversation/conversation.service';import { ActivatedRoute, Router } from '@angular/router';import { Storage } from '@ionic/storage-angular';import { Subscription, interval } from 'rxjs';@Component({ selector: 'app-chat-single', templateUrl: './chat-single.page.html', styleUrls: ['./chat-single.page.scss'], standalone: true, imports: [CommonModule,FormsModule,IonContent,IonHeader,IonTitle,IonToolbar,IonButtons, IonBackButton, IonInput, IonButton, IonIcon, IonSpinner, IonFooter, ], schemas:[CUSTOM_ELEMENTS_SCHEMA]})export class ChatSinglePage implements OnInit {@ViewChild(IonContent, { static: false }) content!: IonContentnewMessageSingle = ""user: any = nullnameUser = ""subjectMatterId = 0studentId = 0isLoading = falsecode: any = nullconversationId = 0typeSend = ""perfilName: any = nullmessages: any[] = []isLoadingMessages = falseconversationIdSelected: any = nullgroupsMessages: any[] = []codeUserCurrent: any = nullprivate messagePollingSubscription: Subscription | null = nullprivate router = inject(Router);private activatedRoute = inject(ActivatedRoute);private conversationService = inject(ConversationService);private storage = inject(Storage);constructor() {const navigation = this.router.getCurrentNavigation();console.log('navigation', navigation?.extras);if (navigation?.extras?.state) {this.user = navigation.extras.state['user'];}this.activatedRoute.queryParams.subscribe((params) => {if (params['user']) {try {this.user = JSON.parse(params['user']);console.log('this user::',this.user)} catch (error) {console.error('Error parsing user data from params:', error);}}});console.log('this is users::', JSON.stringify(this.user, null, 2));if (this.user) {const {fullName = '',subject_matter_id = 0,student_id = 0,conversation_id = 0,type_send = '',code_teacher = null,code_student = null,} = this.user;this.nameUser = fullName || '';this.subjectMatterId = subject_matter_id || 0;this.studentId = student_id || 0;this.conversationId = conversation_id || 0;this.typeSend = type_send || '';this.conversationIdSelected = conversation_id || 0;this.code = code_teacher || code_student || null;console.log('this is studentId', this.studentId);}}async ngOnInit() {console.log('ngOnInit ChatSinglePage');await this.initStorage();}async initStorage() {await this.storage.create();const resultado: any = await this.storage.get('usuario_perfil');console.log('storage current app :::', JSON.stringify(resultado));this.perfilName = resultado?.nombre;this.codeUserCurrent = resultado?.id;}ionViewWillEnter() {console.log('render to another page');this.loadingMessages();this.startMessagePolling();}ionViewWillLeave() {console.log('ionViewWillLeave ChatSinglePage');this.stopMessagePolling();}ngOnDestroy() {this.stopMessagePolling();}startMessagePolling() {this.stopMessagePolling();this.messagePollingSubscription = interval(5000).subscribe(() => {if (!this.isLoadingMessages && !this.isLoading) {this.refreshMessages();}});}stopMessagePolling() {if (this.messagePollingSubscription) {this.messagePollingSubscription.unsubscribe();this.messagePollingSubscription = null;}}async refreshMessages() {if (!this.conversationId || this.conversationId === 0) return;try {const response: any = await this.conversationService.fetchGetMessages(this.conversationId );if (response && response.messages) {if (JSON.stringify(this.messages) !== JSON.stringify(response.messages) ) {console.log('New messages received during polling');this.messages = response.messages;this.groupsMessages = this.groupMessageByDate(this.messages);this.scrollToBottom(300);}}} catch (error) {console.error('Error during message polling:', error);}}sendMessageSingle() {if (!this.newMessageSingle || !this.newMessageSingle.trim()) {return;}console.log('this code user current::', this.codeUserCurrent);const messageData = { messageText: this.newMessageSingle, subjectMatterId: this.subjectMatterId, studentId: this.studentId, conversationId: this.conversationId, typeSend: this.typeSend, createdBy: this.perfilName, codeCreator: this.codeUserCurrent,};this.createMessage(messageData);console.log('this is message single', JSON.stringify(messageData, null, 2));this.scrollToBottom(100);}async createMessage(data: any) {console.log('this is data', JSON.stringify(data, null, 2));this.isLoading = true;try {const response: any = await this.conversationService.fetchCreateMessage(data );console.log('this is response create message',JSON.stringify(response, null, 2) );this.isLoading = false;this.newMessageSingle = '';this.loadingMessages();} catch (error) {console.error('error to moment of get fetchCreateMessage', error);this.isLoading = false;}}async loadingMessages() {this.isLoadingMessages = true;console.log('this is conversationId', this.conversationId);if (!this.conversationId || this.conversationId === 0) {this.isLoadingMessages = false;return;}try {const response: any = await this.conversationService.fetchGetMessages(this.conversationId );console.log('this is response get messages',JSON.stringify(response, null, 2) );this.messages = response.messages || [];this.groupsMessages = this.groupMessageByDate(this.messages);console.log('this is messages group::',JSON.stringify(this.groupsMessages, null, 2) );this.isLoadingMessages = false;this.scrollToBottom(300);} catch (error) {console.error('error to moment of get fetchGetMessages',JSON.stringify(error, null, 2) );this.isLoadingMessages = false;}}formatTime(dateTimeString: string) {if (!dateTimeString) return '';const date = new Date(dateTimeString);let hours = date.getHours();const minutes = date.getMinutes();const ampm = hours >= 12 ? 'p. m.' : 'a. m.';hours = hours % 12;hours = hours ? hours : 12;const formattedMinutes = minutes < 10 ? '0' + minutes : minutes;return ${hours}:${formattedMinutes} ${ampm}
;}scrollToBottom(duration = 300) {setTimeout(() => {if (this.content) {this.content.scrollToBottom(duration);}}, 100);}groupMessageByDate(messages: any[]) {console.log('this is messages', JSON.stringify(messages, null, 2));if (!messages || messages.length === 0) return [];const groupedMessages: any[] = [];const groupsByDate: { [key: string]: any } = {};const today = new Date();today.setHours(0, 0, 0, 0);const yesterday = new Date(today);yesterday.setDate(yesterday.getDate() - 1);messages.forEach((message) => {const messageDate = new Date(message.created_at);messageDate.setHours(0, 0, 0, 0);let dateLabel: string;if (messageDate.getTime() === today.getTime()) {dateLabel = 'Hoy';} else if (messageDate.getTime() === yesterday.getTime()) {dateLabel = 'Ayer';} else {dateLabel = this.formatDate(message.created_at);}if (!groupsByDate[dateLabel]) {groupsByDate[dateLabel] = { label: dateLabel, messages: [],};groupedMessages.push(groupsByDate[dateLabel]);}// add message to the groupgroupsByDate[dateLabel].messages.push(message);});groupedMessages.sort((a, b) => {if (a.label === 'Hoy') return 1;if (b.label === 'Hoy') return -1;if (a.label === 'Ayer') return 1;if (b.label === 'Ayer') return -1;const dateA = new Date(a.messages[0].created_at);const dateB = new Date(b.messages[0].created_at);return dateA.getTime() - dateB.getTime();});return groupedMessages;}formatDate(data: string) {const date = new Date(data.replace(' ', 'T'));const year = date.getFullYear();const month = (date.getMonth() + 1).toString().padStart(2, '0');const day = date.getDate().toString().padStart(2, '0');return ${day}/${month}/${year}
;}}
It seems like the issue is related to the asynchronous nature of ActivatedRoute.queryParams
and the synchronous execution of your constructor. When the constructor runs, the queryParams
subscription might not have emitted a value yet, leading to this.user
being null
or undefined when you try to access it immediately after the subscription setup.
Additionally, router.getCurrentNavigation()?.extras?.state
is primarily useful for passing state between routes when navigating programmatically (e.g., using router.navigate
), but this state is often lost on page refresh or direct URL access. Query parameters are generally more robust for initial data on component load.
To fix this, you should:
this.user
to ngOnInit
or a dedicated method. ngOnInit
is guaranteed to run after the component's inputs have been initialized and after the constructor.queryParams
subscription is handled correctly and that the this.user
object is processed only when it's available.Here's the revised ChatSinglePage
component:
Key Changes and Explanation:
user
data is moved out.ngOnInit
for Data Loading:
this.activatedRoute.queryParams.subscribe()
is still used, but the processing of this.user
and subsequent initialization (initializeUserData()
) is now inside the subscription callback. This ensures that this.user
is populated before its properties are accessed.queryParamsSubscription
is introduced to manage the subscription, which is then unsubscribed in ngOnDestroy
to prevent memory leaks.router.getCurrentNavigation()?.extras?.state
is included, but queryParams
is prioritized as it's more reliable for initial loads and direct URL access.initializeUserData()
Method: This new private method encapsulates all the logic that depends on the this.user
object. It's called only after this.user
has been successfully parsed from the query parameters or retrieved from the navigation state. This ensures that nameUser
, subjectMatterId
, studentId
, conversationId
, etc., are set correctly.ionViewWillEnter
Adjustment: The logic to load messages and start polling is now conditional on this.user
and this.conversationId
being set, preventing issues if the view is entered before the data is fully initialized.ngOnDestroy
Cleanup: Added this.queryParamsSubscription.unsubscribe()
to properly clean up the subscription when the component is destroyed.How to pass the user
object when navigating:
When navigating to ChatSinglePage
, you need to ensure the user
object is correctly stringified and passed as a query parameter.
Using router.navigate
(in another component):
import { Router } from '@angular/router';
// ... inside your component where you navigate
constructor(private router: Router) {}
navigateToChat(userObject: any) {
this.router.navigate(['/chat-single'], {
queryParams: {
user: JSON.stringify(userObject) // IMPORTANT: Stringify the object here
}
});
}
Using routerLink
in HTML:
<!-- Assuming 'user' is an object in your component's context -->
<a [routerLink]="['/chat-single']" [queryParams]="{ user: user | json }">Go to Chat</a>
The | json
pipe in Angular templates automatically stringifies the object for you.
By making these changes, your this.user
object should be correctly populated and its properties accessible when the component's logic that depends on it executes.