Search code examples
angularangular6angular-servicesscreen-size

How to get a screen resize dimension from a service in angular 2+?


First this not duplicated take time to read, because there is lot of similar question but they are in the @Component decorator

I got the idea to catch screen resizing in a service then sharing some css value by an observable, but it seem that my service is not working (not able to catch screen resize event).

Here is my code

import { Injectable, HostListener } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
 providedIn: 'root',
})
export class BreakPointService {

    normal: {
        background: 'w3-teal',
        inputColor: 'w3-light-grey',
        css_parent: 'w3-container w3-teal'
    };
    breakpoint: {
        background: 'w3-dark-blue',
        inputColor: 'w3-white',
        css_parent: 'w3-container w3-light-grey'
    };
    breakPointValue: number;


    css_behaviour = new BehaviorSubject(JSON.stringify(this.breakpoint));

    current_css = this.css_behaviour.asObservable();

    @HostListener('window:resize', ['$event'])
    onResize(event) {
        console.log();
        this.breakPointValue = window.innerWidth;
        console.log(this.breakPointValue);
        if (this.breakPointValue > 768) {
            console.log(JSON.stringify(this.normal));
            this.css_behaviour.next(JSON.stringify(this.normal));
        } else {
            console.log(JSON.stringify(this.breakpoint));
            this.css_behaviour.next(JSON.stringify(this.breakpoint));
        }
    }

    public css() {
        if (this.breakPointValue > 768) {
            return this.normal;
        }
        return this.breakpoint;

    }

    constructor() { }
}

Is there any way to do this or this is incheavable from a service ?


Solution

  • So I did not see in your OP where you are initializing the service. I had to do this almost exact thing in one app. We watch for screen size changes which triggers changes in some user preferences in local storage:

    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs/BehaviorSubject';
    import { TableViewTypes, MediaSizes, UserPreferencesDefaults, TableView, getTableViewDefaults } from '../models/user-preferences.model';
    import { StorageService } from './storage.service';
    
    @Injectable()
    export class UserPreferencesService {
    
        private tableViewSubject = new BehaviorSubject<TableView>(UserPreferencesDefaults.tableView);
        tableView$ = this.tableViewSubject.asObservable();
    
        constructor(
            private storageService: StorageService
        ) {}
    
        init() {
            this.tableViewSubject.next(
                !(window.outerWidth > MediaSizes.sm) ?
                getTableViewDefaults(false) :
                UserPreferencesDefaults.tableView
            );
            window.addEventListener('resize', () => {
                this.tableViewSubject.next(
                    !(window.outerWidth > MediaSizes.sm) ?
                    getTableViewDefaults(false) :
                    this.storageService.userPreferences.tableView
                );
            });
        }
    
        storeTableView(tableType: TableViewTypes, value: boolean) {
            this.storageService.userPreferences = {
                ...this.storageService.userPreferences,
                tableView: {
                    ...this.storageService.userPreferences.tableView,
                    [tableType]: value
                }
            };
        }
    
        toggleTableView(tableType: TableViewTypes, value?: boolean) {
            value = value !== undefined && value !== null ? value : !this.storageService.userPreferences.tableView[tableType];
            this.tableViewSubject.next({
                ...this.storageService.userPreferences.tableView,
                [tableType]: value
            });
            this.storeTableView(tableType, value);
        }
    
    }
    

    Then in order for the service to work it is initialized by injecting it into the app.component.ts in the constructor param

    constructor(
        private userPreferenceService: UserPreferencesService,
    ) {this.userPreferenceService.init();}