Overview
The UserService provides methods for retrieving and updating user profile information, including personal details, contact information, and verification status.
Location : src/app/core/services/http/user.service.ts
Public Methods
getProfile()
Retrieves the authenticated user’s complete profile.
Use HTTP-only cookie for authentication (default: true)
Returns : Observable<UserProfile>
Whether email is verified
Whether phone is verified
this . userService . getProfile ( true ). subscribe ({
next : ( profile ) => {
console . log ( 'User profile:' , profile );
this . displayName = ` ${ profile . firstName } ${ profile . lastName } ` ;
this . email = profile . email ;
}
});
updateProfile()
Updates the user’s profile information.
The user’s unique identifier
payload
UpdateUserPayload
required
Profile update data (all fields optional) Show UpdateUserPayload Properties
Updated email address (requires re-verification)
Updated phone number (requires re-verification)
Updated profile photo URL
Returns : Observable<UserProfile>
const updates : UpdateUserPayload = {
firstName: 'Juan' ,
lastName: 'Rodriguez' ,
phone: '+53-5-1234567'
};
this . userService . updateProfile ( userId , updates ). subscribe ({
next : ( updatedProfile ) => {
console . log ( 'Profile updated:' , updatedProfile );
if ( updates . phone && ! updatedProfile . phoneVerified ) {
this . showMessage ( 'Please verify your new phone number' );
}
}
});
uploadProfilePhoto()
Uploads a new profile photo.
The user’s unique identifier
Returns : Observable<{ photoUrl: string }>
onFileSelected ( event : Event ) {
const input = event . target as HTMLInputElement ;
if ( input . files && input . files [ 0 ]) {
const file = input . files [ 0 ];
// Validate file type and size
if ( ! file . type . startsWith ( 'image/' )) {
this . showError ( 'Please select an image file' );
return ;
}
if ( file . size > 5 * 1024 * 1024 ) { // 5MB limit
this . showError ( 'Image must be smaller than 5MB' );
return ;
}
this . userService . uploadProfilePhoto ( this . userId , file ). subscribe ({
next : ( response ) => {
this . photoUrl = response . photoUrl ;
this . showMessage ( 'Profile photo updated' );
},
error : ( error ) => {
this . showError ( 'Failed to upload photo' );
}
});
}
}
verifyEmail()
Initiates email verification process.
Returns : Observable<void>
this . userService . verifyEmail ( this . user . email ). subscribe ({
next : () => {
this . showMessage ( 'Verification email sent. Please check your inbox.' );
}
});
verifyPhone()
Initiates phone verification process.
Returns : Observable<void>
this . userService . verifyPhone ( this . user . phone ). subscribe ({
next : () => {
this . showMessage ( 'Verification code sent via SMS' );
this . showCodeInput = true ;
}
});
confirmPhoneVerification()
Confirms phone verification with the code sent via SMS.
Phone number being verified
6-digit verification code
Returns : Observable<UserProfile>
this . userService . confirmPhoneVerification ( this . user . phone , this . verificationCode ). subscribe ({
next : ( profile ) => {
if ( profile . phoneVerified ) {
this . showMessage ( 'Phone verified successfully!' );
}
},
error : ( error ) => {
if ( error . code === 'INVALID_CODE' ) {
this . showError ( 'Invalid verification code' );
} else if ( error . code === 'CODE_EXPIRED' ) {
this . showError ( 'Verification code expired. Request a new one.' );
}
}
});
Profile Management Flow
Load Profile
Fetch the user’s current profile data on component initialization
Display Form
Pre-fill form fields with existing profile data
Handle Changes
Validate inputs as user makes changes
Submit Updates
Send only changed fields to minimize data transfer
Handle Verification
If email/phone changed, prompt for verification
Refresh Profile
Reload profile data to reflect server-side changes
Complete Profile Component Example
import { Component , inject , OnInit } from '@angular/core' ;
import { FormBuilder , FormGroup , Validators } from '@angular/forms' ;
import { UserService } from '@/app/core/services/http/user.service' ;
import { UserProfile } from '@/app/core/models/user/user.response' ;
@ Component ({
selector: 'app-profile-edit' ,
templateUrl: './profile-edit.component.html' ,
})
export class ProfileEditComponent implements OnInit {
private userService = inject ( UserService );
private fb = inject ( FormBuilder );
profileForm : FormGroup ;
profile ?: UserProfile ;
loading = false ;
ngOnInit () {
this . profileForm = this . fb . group ({
firstName: [ '' , Validators . required ],
lastName: [ '' , Validators . required ],
email: [ '' , [ Validators . required , Validators . email ]],
phone: [ '' , Validators . required ]
});
this . loadProfile ();
}
loadProfile () {
this . loading = true ;
this . userService . getProfile (). subscribe ({
next : ( profile ) => {
this . profile = profile ;
this . profileForm . patchValue ({
firstName: profile . firstName ,
lastName: profile . lastName ,
email: profile . email ,
phone: profile . phone
});
this . loading = false ;
},
error : ( error ) => {
console . error ( 'Failed to load profile:' , error );
this . loading = false ;
}
});
}
saveProfile () {
if ( this . profileForm . invalid || ! this . profile ) {
return ;
}
const updates = this . profileForm . value ;
this . loading = true ;
this . userService . updateProfile ( this . profile . id , updates ). subscribe ({
next : ( updatedProfile ) => {
this . profile = updatedProfile ;
this . loading = false ;
// Check if verification needed
if ( updates . email !== this . profile . email && ! updatedProfile . emailVerified ) {
this . promptEmailVerification ();
}
if ( updates . phone !== this . profile . phone && ! updatedProfile . phoneVerified ) {
this . promptPhoneVerification ();
}
},
error : ( error ) => {
console . error ( 'Failed to update profile:' , error );
this . loading = false ;
}
});
}
promptEmailVerification () {
// Show verification UI
}
promptPhoneVerification () {
// Show verification UI
}
}
Best Practices
Optimistic updates : Update the UI immediately while the API call is in progress for better perceived performance.
Verification required : Always prompt users to verify their email/phone after changing them.
Profile photos : Resize images on the client side before uploading to reduce bandwidth usage.