Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSR MatchMedia not working #991

Closed
dottodot opened this issue Jan 14, 2019 · 6 comments · Fixed by #999
Closed

SSR MatchMedia not working #991

dottodot opened this issue Jan 14, 2019 · 6 comments · Fixed by #999
Assignees
Labels
feature has pr A PR has been created to address this issue P5 Low-priority issue that needs consideration
Milestone

Comments

@dottodot
Copy link

dottodot commented Jan 14, 2019

Bug Report

What is the expected behavior?

I've add the server module as instructed here https://github.com/angular/flex-layout/wiki/Using-SSR-with-Flex-Layout

I've tried with MatchMedia and MediaObserver and I get the same result but the following always returns false in SSR regardless of screen width.

export class FeaturedComponent implements OnInit {
  constructor(public match: MatchMedia, public media: MediaObserver) {}

  ngOnInit() {
    console.log('gt-md', this.media.isActive('gt-md'));
    console.log(
      'gt-md match',
      this.match.isActive('screen and (min-width: 600px)')
    );
  }
}

Before I try to make a reproducible repo, have I missed anything that would make it work, and should it work?

Something else that's slightly odd is if I subscribe to MatchMedia and MediaObserver at the same time the logs on the server side seems to suggest it's finding matches, which doesn't happen if I subscribe to one or the other.

    this.match
      .observe(['screen and (min-width: 768px)'])
      .subscribe((change: MediaChange) => {
        console.log('match', change);
      });

    this.media.media$.subscribe((change: MediaChange) => {
      console.log('media', change);
    });
MatchMedia activations ``` match MediaChange { matches: true, mediaQuery: 'all', mqAlias: '', suffix: '', property: '' } media MediaChange { matches: true, mediaQuery: 'all', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (min-width: 600px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (min-width: 960px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (min-width: 1280px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (min-width: 1920px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (min-width: 1920px) and (max-width: 5000px)', mqAlias: '', suffix: '', property: '' } media MediaChange { matches: true, mediaQuery: 'screen and (min-width: 1920px) and (max-width: 5000px)', mqAlias: 'xl', suffix: 'Xl', property: '' } match MediaChange { matches: false, mediaQuery: 'screen and (min-width: 1920px) and (max-width: 5000px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (max-width: 1919px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (min-width: 1280px) and (max-width: 1919px)', mqAlias: '', suffix: '', property: '' } media MediaChange { matches: true, mediaQuery: 'screen and (min-width: 1280px) and (max-width: 1919px)', mqAlias: 'lg', suffix: 'Lg', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (max-width: 1279px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: false, mediaQuery: 'screen and (max-width: 1279px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (min-width: 960px) and (max-width: 1279px)', mqAlias: '', suffix: '', property: '' } media MediaChange { matches: true, mediaQuery: 'screen and (min-width: 960px) and (max-width: 1279px)', mqAlias: 'md', suffix: 'Md', property: '' } match MediaChange { matches: false, mediaQuery: 'screen and (max-width: 1919px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (max-width: 959px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: false, mediaQuery: 'screen and (min-width: 600px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (min-width: 600px) and (max-width: 959px)', mqAlias: '', suffix: '', property: '' } media MediaChange { matches: true, mediaQuery: 'screen and (min-width: 600px) and (max-width: 959px)', mqAlias: 'sm', suffix: 'Sm', property: '' } match MediaChange { matches: false, mediaQuery: 'screen and (min-width: 960px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (max-width: 599px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: false, mediaQuery: 'screen and (min-width: 1280px)', mqAlias: '', suffix: '', property: '' } match MediaChange { matches: true, mediaQuery: 'screen and (min-width: 0px) and (max-width: 599px)', mqAlias: '', suffix: '', property: '' } media MediaChange { matches: true, mediaQuery: 'screen and (min-width: 0px) and (max-width: 599px)', mqAlias: 'xs', suffix: 'Xs', property: '' } match MediaChange { matches: false, mediaQuery: 'screen and (min-width: 1920px)', mqAlias: '', suffix: '', property: '' } ```

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular CLI: 7.2.1
Node: 10.13.0
OS: darwin x64
Angular: 7.2.0
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
... service-worker

Package Version

@angular-devkit/architect 0.12.1
@angular-devkit/build-angular 0.12.1
@angular-devkit/build-optimizer 0.12.1
@angular-devkit/build-webpack 0.12.1
@angular-devkit/core 7.2.1
@angular-devkit/schematics 7.2.1
@angular/cdk 7.2.1
@angular/cli 7.2.1
@angular/flex-layout 7.0.0-beta.23
@angular/material 7.2.1
@angular/material-moment-adapter 7.2.1
@angular/pwa 0.10.7
@ngtools/webpack 7.2.1
@schematics/angular 7.0.7
@schematics/update 0.12.1
rxjs 6.3.3
typescript 3.2.2
webpack 4.23.1

@CaerusKaru
Copy link
Member

That’s the documented behavior on the server, and I’m afraid it’s unavoidable. When you’re on the server, there is no “browser size,” so Flex Layout punches out temporary static CSS for all compatible directives by iteratively activating and deactivating all the breakpoints in order. This means that MatchMedia and MediaObserver won’t report which one is active, because technically none of them are.

I’m going to leave this open because theee was discussion at some point of adding a fallback value for isActive during SSR, and we should probably do that now.

@CaerusKaru CaerusKaru added feature P5 Low-priority issue that needs consideration labels Jan 14, 2019
@dottodot
Copy link
Author

OK thanks, although I think the docs are a little misleading, the opening line is

@angular/flex-layout now supports server-side rendering (SSR).

and the last part

also substitutes the version of MatchMedia with a server-compatible implementation called ServerMatchMedia

both kind of suggest that MatchMedia will work on the server. I did think I was being overly optimistic.

@CaerusKaru CaerusKaru self-assigned this Jan 15, 2019
@CaerusKaru CaerusKaru added this to the 7.0.0-beta.24 milestone Jan 15, 2019
@CaerusKaru
Copy link
Member

Again, we intended to add it as an option and I think it got lost in the shuffle (hence the docs misread). We're going to get this in for the next release, I'm just waiting on @ThomasBurleson's new MediaTrigger service, which should make this a lot easier.

@CaerusKaru CaerusKaru added the has pr A PR has been created to address this issue label Jan 15, 2019
@CaerusKaru
Copy link
Member

This will be patched in #999. Turns out we didn't need MediaTrigger, but that doesn't really matter.

In the new syntax, you'll be able to specify the activations you want on the server when setting up the module:

FlexLayoutModule.withConfig({serverBreakpoints: ['md', 'gt-sm']})

@CaerusKaru
Copy link
Member

I've also updated the SSR page on the Wiki to reflect this.

ThomasBurleson pushed a commit that referenced this issue Jan 16, 2019
)

On the server, there is no conception of "browser window," because Angular's
browser implementation doesn't implement it. This means MatchMedia breakpoint activations will not work on the server. 

Layout SSR will generate CSS Stylesheets for all known breakpoints. And for the static, delivered-first HTML pages the directives are replaced with their associated, generated CSS classnames. 

But for programmatic usages of `MediaObserver`, we don't have a fallback mechanism to *announce* breakpoint activations. This PR allows a user to specify which activations they want to trigger via the MediaObserver for programmatic view listeners.

This can be done using the following configuration:

```ts
FlexLayoutModule.withConfig({serverBreakpoints: ['xs', 'lt-md']})
```

Fixes #991 .
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature has pr A PR has been created to address this issue P5 Low-priority issue that needs consideration
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants