[A] user.service, edit username in profile
This commit is contained in:
parent
ccde75f72a
commit
ef07db5818
7 changed files with 249 additions and 12 deletions
|
|
@ -1,7 +1,8 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { createClient, SupabaseAuthUser, SupabaseClient } from '@supabase/supabase-js'
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { Subject } from 'rxjs';
|
||||
import { environment } from '../../../environments/environment'
|
||||
import { User } from './user';
|
||||
|
||||
|
||||
@Injectable({
|
||||
|
|
@ -9,7 +10,9 @@ import { environment } from '../../../environments/environment'
|
|||
})
|
||||
export class SupaService {
|
||||
client: SupabaseClient;
|
||||
user: BehaviorSubject<SupabaseAuthUser> = new BehaviorSubject(null);
|
||||
user: Subject<SupabaseAuthUser> = new Subject();
|
||||
supabaseUser: SupabaseAuthUser;
|
||||
userProfile: User;
|
||||
|
||||
constructor() {
|
||||
// Create a single supabase client for interacting with your database
|
||||
|
|
@ -20,9 +23,39 @@ export class SupaService {
|
|||
async getUser() {
|
||||
const user = await this.client.auth.user();
|
||||
console.log('user', user);
|
||||
this.supabaseUser = user;
|
||||
this.getUserProfile();
|
||||
this.user.next(user);
|
||||
}
|
||||
|
||||
getUserProfile(user_id: string = this.supabaseUser.id) {
|
||||
const subject: Subject<User> = new Subject();
|
||||
if (!this.userProfile) {
|
||||
this.client.from<User>('user').select().match({id: <never>user_id})
|
||||
.then(data => {
|
||||
console.log('getUserProfile', data)
|
||||
if (data.body.length === 0) {
|
||||
// create default user profile
|
||||
this.client.from<User>('user').insert(new User(user_id, this.supabaseUser.email.split('@')[0]))
|
||||
.then(data => {
|
||||
console.log('created UserProfile', data.body[0]);
|
||||
this.userProfile = data.body[0];
|
||||
subject.next(this.userProfile);
|
||||
})
|
||||
.catch(error => console.error('Error creating UserProfile', error))
|
||||
} else {
|
||||
console.log('loaded UserProfile', data.body[0]);
|
||||
this.userProfile = data.body[0];
|
||||
subject.next(this.userProfile);
|
||||
}
|
||||
})
|
||||
.catch(error => console.error('getUserProfile', error))
|
||||
} else {
|
||||
setTimeout(() =>subject.next(this.userProfile), 100);
|
||||
}
|
||||
return subject.asObservable();
|
||||
}
|
||||
|
||||
async login(email: string, password: string): Promise<SupabaseAuthUser> {
|
||||
try {
|
||||
const res = await this.client.auth.login(
|
||||
|
|
|
|||
16
src/app/api/supabase/user.service.spec.ts
Normal file
16
src/app/api/supabase/user.service.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UserService } from './user.service';
|
||||
|
||||
describe('UserService', () => {
|
||||
let service: UserService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(UserService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
159
src/app/api/supabase/user.service.ts
Normal file
159
src/app/api/supabase/user.service.ts
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
|
||||
import { map } from 'rxjs/internal/operators/map';
|
||||
import { SupaService } from './supa.service';
|
||||
import { User } from './user';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserService {
|
||||
userMap = {};
|
||||
users: BehaviorSubject<User[]> = new BehaviorSubject(Object.values(this.userMap));
|
||||
isListening: boolean = true;
|
||||
|
||||
constructor(
|
||||
private supa: SupaService,
|
||||
) { }
|
||||
|
||||
/**
|
||||
* Get Users from local store.
|
||||
* Requests data if store is emtpy.
|
||||
* @returns Observable<User[]>
|
||||
*/
|
||||
getStories(): Observable<User[]> {
|
||||
if (Object.values(this.userMap).length === 0) {
|
||||
this.subscribeToUsers();
|
||||
console.log('getUsers- REFRESH')
|
||||
this.supa.client.from<User>('user').select()
|
||||
.then(data => {
|
||||
this.updateStore(data.body);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
return this.users.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to realtime events from users db.
|
||||
*/
|
||||
subscribeToUsers() {
|
||||
if (!this.isListening) {
|
||||
this.isListening = true;
|
||||
this.supa.client.from<User>('user').on('*', payload => {
|
||||
console.log('subscribeToStories - REALTIME EVENT', payload)
|
||||
if ((payload.eventType === 'INSERT') || (payload.eventType === 'UPDATE')) {
|
||||
this.userMap[payload.new.id] = payload.new;
|
||||
} else {
|
||||
delete this.userMap[payload.old.id];
|
||||
}
|
||||
this.next();
|
||||
}).subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the local store with provided users
|
||||
* @param users
|
||||
*/
|
||||
updateStore(users: User[]) {
|
||||
users.forEach(e => {
|
||||
// this.userMap.set(e.id, e);
|
||||
this.userMap[e.id] = e;
|
||||
});
|
||||
console.log('update users', this.userMap)
|
||||
this.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits local store.
|
||||
*/
|
||||
next = () => {
|
||||
console.log('next', Object.values(this.userMap))
|
||||
this.users.next(Object.values(this.userMap))
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve users from local store.
|
||||
* @param id
|
||||
*/
|
||||
getOne(id: number) {
|
||||
if (this.userMap[id]) {
|
||||
return of(this.userMap[id]);
|
||||
} else {
|
||||
const subject: Subject<User> = new Subject();
|
||||
this.supa.client.from<User>('user').select('id, name, description')
|
||||
.filter(<never>'id', 'eq', id)
|
||||
.then(data => {
|
||||
this.updateStore([data.body[0]]);
|
||||
subject.next(data.body[0]);
|
||||
subject.complete();
|
||||
})
|
||||
.catch(error => {
|
||||
subject.error(error);
|
||||
subject.complete();
|
||||
});
|
||||
return subject.asObservable();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a users data.
|
||||
* @param users
|
||||
*/
|
||||
updateOne(user: User): Observable<User> {
|
||||
const subject: Subject<User> = new Subject();
|
||||
this.supa.client.from<User>('user').update(user)
|
||||
.match({ id: user.id })
|
||||
.then(data => {
|
||||
subject.next(data.body[0]);
|
||||
subject.complete();
|
||||
})
|
||||
.catch(error => {
|
||||
subject.error(error);
|
||||
subject.complete();
|
||||
});
|
||||
return subject.asObservable();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes one user from db.
|
||||
* @param user
|
||||
*/
|
||||
deleteOne(user: User): Observable<User> {
|
||||
const subject: Subject<User> = new Subject();
|
||||
this.supa.client.from<User>('user').delete()
|
||||
.match({ id: user.id })
|
||||
.then(data => {
|
||||
subject.next(user);
|
||||
subject.complete();
|
||||
})
|
||||
.catch(error => {
|
||||
subject.error(error);
|
||||
subject.complete();
|
||||
});
|
||||
return subject.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a user on the db.
|
||||
* @param users
|
||||
*/
|
||||
addOne(user: User): Observable<User> {
|
||||
const subject: Subject<User> = new Subject();
|
||||
this.supa.client.from<User>('user').insert(user)
|
||||
.then(data => {
|
||||
subject.next(data.body[0]);
|
||||
subject.complete();
|
||||
})
|
||||
.catch(error => {
|
||||
subject.error(error);
|
||||
subject.complete();
|
||||
});
|
||||
return subject.asObservable();
|
||||
}
|
||||
|
||||
}
|
||||
11
src/app/api/supabase/user.ts
Normal file
11
src/app/api/supabase/user.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
export class User {
|
||||
id: string;
|
||||
status: 'OFFLINE' |'ONLINE';
|
||||
username: string;
|
||||
|
||||
constructor(id: string, username: string, status: 'OFFLINE' | 'ONLINE' = 'ONLINE') {
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import { FormsModule } from '@angular/forms';
|
|||
import { SupaService } from './api/supabase/supa.service';
|
||||
import { StandupService } from './api/supabase/standup.service';
|
||||
import { StoryService } from './api/supabase/story.service';
|
||||
import { UserService } from './api/supabase/user.service';
|
||||
import { AuthGuard } from './authguard.service';
|
||||
|
||||
import { AppComponent } from "./app.component";
|
||||
|
|
@ -42,6 +43,7 @@ import { DashboardComponent } from './dashboard/dashboard.component';
|
|||
SupaService,
|
||||
StandupService,
|
||||
StoryService,
|
||||
UserService,
|
||||
AuthGuard,
|
||||
],
|
||||
bootstrap: [
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
<legend>Profile</legend>
|
||||
<pre>
|
||||
<code *ngIf="user">
|
||||
{{ user | json }}
|
||||
</code>
|
||||
</pre>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-3">
|
||||
<legend>Profile</legend>
|
||||
<form *ngIf="user">
|
||||
<div class="form-group">
|
||||
<label for="username">Username</label>
|
||||
<input type="text" class="form-control" name="username" aria-describedby="Input for username." [(ngModel)]="user.username">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" (submit)="updateUser()" (click)="updateUser()">Save</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { SupabaseAuthUser } from '@supabase/supabase-js';
|
||||
import { SupaService } from '../api/supabase/supa.service';
|
||||
import { User } from '../api/supabase/user';
|
||||
import { UserService } from '../api/supabase/user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-profile',
|
||||
|
|
@ -8,17 +10,25 @@ import { SupaService } from '../api/supabase/supa.service';
|
|||
styleUrls: ['./profile.component.scss']
|
||||
})
|
||||
export class ProfileComponent implements OnInit {
|
||||
user: SupabaseAuthUser;
|
||||
user: User;
|
||||
|
||||
constructor(
|
||||
public supa: SupaService,
|
||||
private supaService: SupaService,
|
||||
private userService: UserService,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.supa.client.auth.user().then(user => {
|
||||
console.log('user', user)
|
||||
this.supaService.getUserProfile().subscribe((user:User) => {
|
||||
console.log('user', user);
|
||||
this.user = user;
|
||||
});
|
||||
}
|
||||
|
||||
updateUser() {
|
||||
this.userService.updateOne(this.user).subscribe(
|
||||
data => console.log('Success', data),
|
||||
error => console.error(error)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue