Reputation: 13
`Hello i am using the BreakpointObserver and try to emit 2 breakpoints. One for mobile and one for tablet. But the problem is it works for the Tablet but not for the mobile. In the switch statement it never reaches the mobile one. Because i have tested it with console.log().
private breakPointBehaviorSubject$ = new BehaviorSubject<Breakpoint>(Breakpoint.DESKTOP);
constructor(private breakpointObserver: BreakpointObserver) {
this.breakpointObserver.observe([ '(max-width: 800px)', '(max-width: 1200px)']).subscribe(result =>{
const breakpoints = result.breakpoints;
console.log(breakpoints);
switch(true) {
case breakpoints['(max-width: 1200px)']:
this.breakPointBehaviorSubject$.next(Breakpoint.TABLET);
console.log('Tablet ' + breakpoints['(max-width: 1200px)']);
break;
case breakpoints['(max-width: 800px)']:
this.breakPointBehaviorSubject$.next(Breakpoint.MOBILE);
console.log('Mobile ' + breakpoints['(max-width: 800px)']);
break;
default:
this.breakPointBehaviorSubject$.next(Breakpoint.DESKTOP);
break;
}
});
}
get breakpointObservable$() {
return this.breakPointBehaviorSubject$.asObservable();
}
}`
Upvotes: 0
Views: 3638
Reputation: 13
I fixed the problem with two seperate observers, but i don't know if it is the right way.
private isMobile$ = new BehaviorSubject<boolean>(false);
private isTablet$ = new BehaviorSubject<boolean>(false);
constructor(private breakpointObserver: BreakpointObserver) {
this.breakpointObserver.observe(['(max-width: 800px)']).pipe(map(breakpoint => {
this.isMobile$.next(breakpoint.matches);
})).subscribe();
this.breakpointObserver.observe(['(max-width: 1200px)']).pipe(map(breakpoint => {
this.isTablet$.next(breakpoint.matches);
})).subscribe();
}
get breakpointMobile$() {
return this.isMobile$.asObservable();
}
get breakpointTablet$() {
return this.isTablet$.asObservable();
}
Upvotes: 0
Reputation: 1633
So the issue is with the fact that the posted code blocks check for just one condition. But you want both conditions should report if that's the case.
Like in the switch statement you posted, because you are detecting for true
, once the first case passes, the switch returns (because of the break statement). If you go ahead to reorder the cases, the same problem will be occurring. TypeScript doesn't permit fall through so switch won't be the solution.
If statements should solve this problem @ferhado's answer uses if-else blocks. This prevents one breakpoint from emitting if the other has emitted and technically is the same problem with switch. I tried editing but couldn't and had to paste this.
So use if statements independent of each other and you would be good. Something like the following
const breakpoints = result.breakpoints;
console.log(breakpoints);
if (breakpoints['(max-width: 800px)']) {
this.breakPointBehaviorSubject$.next(Breakpoint.MOBILE);
console.log('Mobile ' + breakpoints['(max-width: 800px)']);
}
if (breakpoints['(max-width: 1200px)']) {
this.breakPointBehaviorSubject$.next(Breakpoint.TABLET);
console.log('Tablet ' + breakpoints['(max-width: 1200px)']);
}
So any time the console logs 'Mobile true', expect it to equally log 'Tablet true'. The reason is when the device width is less than 800px, it is also less than 1200px. I suppose this solves the problem.
Upvotes: 0
Reputation: 2604
Just change the condition and check the smallest one at first:
const breakpoints = result.breakpoints;
console.log(breakpoints);
if (breakpoints['(max-width: 800px)']) {
console.log("Mobile");
} else if (breakpoints['(max-width: 1200px)']) {
console.log("Tablet");
} else {
console.log("Desktop");
}
Upvotes: 1