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

Router resolved data does not persist in ActivatedRoute data after navigation #12306

Closed
michaelchiche opened this issue Oct 14, 2016 · 19 comments

Comments

@michaelchiche
Copy link
Contributor

michaelchiche commented Oct 14, 2016

I'm submitting a ... (check one with "x")

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior
The router resolved properties are not persisted inside the ActivatedRoute data unlike the data properties.

Expected behavior
The router resolved properties should be persisted inside the ActivatedRoute data like the data properties.

Minimal reproduction of the problem with instructions
http://plnkr.co/edit/twhzHaywqxVDPhD2R1NT?p=preview

What is the motivation / use case for changing the behavior?
Some motivations are:

  • Preload data application wide
  • Reuse preloaded data

Please tell us about your environment:

  • Angular version: 2.1.0

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]

  • Language: [all | TypeScript X.X | ES6/7 | ES5]

  • Node (for AoT issues): node --version = v6.8.0

@michaelchiche michaelchiche changed the title Router: router resolved data does not persist in ActivatedRoute data after navigation Router resolved data does not persist in ActivatedRoute data after navigation Oct 14, 2016
@olegdunkan
Copy link
Contributor

@michaelchiche You can access this data through parent.
Try replace:

this.data = this.route.snapshot.data;

with this:

this.data = this.route.parent.snapshot.data;

You will get it all.

The real question is why when we first resolved data the data is flatted but when we go upward of url tree we must access data exactly at the node which defined it.

@michaelchiche
Copy link
Contributor Author

@olegdunkan What you say is true, but I am not looking for a hack. It works for simple routes, but what happens when I have 3 or more different nesting levels of children?

From what I understand, I am supposed to be able to access the data resolved after navigation inside the data property, which is not the case.

@olegdunkan
Copy link
Contributor

olegdunkan commented Oct 18, 2016

@michaelchiche it is not hack, it is the way you can access data from parents, you can write simply function that go upward to any level. 'Parent' is a public property of route and snapshot. I didn't see any reasons do not use it. More then this it is the right way to get data from parents. How do you think to implement all data at all levels? Let say we have n levels and all levels resolves to data, in first level we have one property of data, next level adds one more, and finally we have n(n+1)/2 properties and n^2 complexity. Of course we can use prototyping but this is the same like parent property.

function getParentData(snapshot:any, level:number) {
  var ref = snapshot;

  while (level--) {
     ref = ref.parent;     
  }
  return ref.data;
}

@michaelchiche
Copy link
Contributor Author

@olegdunkan: that's not the point... I am not asking how to do it...

I am filing a bug report because the documentation says that it is suppose to work without additional work.

@olegdunkan
Copy link
Contributor

@michaelchiche could you please give me the link where it is described in documentation?

@michaelchiche
Copy link
Contributor Author

michaelchiche commented Oct 18, 2016

@olegdunkan: Are you being serious? if you don't know what you are talking about, please do not pollute the issue. thanks...

And for your information, it is said here: https://angular.io/docs/ts/latest/guide/router.html#!#activated-route

data: An Observable that contains the data object provided for the route. Also contains any resolved values from the resolve guard.

You can also check my plunker ;)

@olegdunkan
Copy link
Contributor

olegdunkan commented Oct 18, 2016

The same question was asked at the vsavkin.com blog he answered that we have to use parent property.

It is what I want to say, how it works

{
    path: 'a',
    component:A,
    resolve: {
      A: AResolver // it is GOUARD not GOURDS
    },
    children: [
      {
        path: 'b',
        component:B,
        resolve: {
            B: BResolver  
        },
        children: [
        {
           path: 'c',
           component:C,
           resolve: {
               C: CResolver  
           }
        }
      }
    ]
  }


in A component 
onInit() {
  this.route.data.subscribe(data=> {
  //data = {A:...} 
  });
}

in B component 
onInit() {
  this.route.data.subscribe(data=> {
  //have to be data = {B:...}, not data = {A:.., B:..}
  });
  this.route.parent.data.subscribe(data=> {
  //data = {A:...}
  });
}

in C component 
onInit() {
  this.route.data.subscribe(data=> {
  //data = {C:...} 
  //have to be data = {C:...}, not data = {A:.., B:.., C:..}
  });
  this.route.parent.data.subscribe(data=> {
  //data = {B:...}
  });
  this.route.parent.parent.data.subscribe(data=> {
  //data = {A:...}
  });
}

I repeat the real question why you get data at first. It wouldn't be that way.

Documentation says common words you can't conclude exactly that data gathered from levels above.
Wait for officials what they will say.

@DzmitryShylovich
Copy link
Contributor

I repeat the real question why you get data at first. It wouldn't be that way.

+1. that's the real issue

@michaelchiche
Copy link
Contributor Author

@DzmitryShylovich @olegdunkan No.
And talking of vssavkin's blog. Here is what I want to do: https://vsavkin.com/the-powerful-url-matching-engine-of-angular-router-775dad593b03#7e93

In his gist, he shows how to share resolved data between child components... Look at the plunker please

@DzmitryShylovich
Copy link
Contributor

DzmitryShylovich commented Oct 18, 2016

http://plnkr.co/edit/NgDlGWjrMQC8pMVzSVkA?p=preview this is the correct plunker and expected behavior.

Did he write anything about data availability in his blog? No.

@olegdunkan
Copy link
Contributor

olegdunkan commented Oct 18, 2016

@michaelchiche he (Victor) shows us how to share, not how to access data.
Access to resolved data has the same shape, via data property just so. If you define 'resolve' section in parent you have to get data from parent if you define section in parent parent please be patient and get it from parent parent.

@michaelchiche
Copy link
Contributor Author

so can you explain why I can access the data defined in the data property of the parent without calling parent.data, but not the data inside the resolver, since, I repeat myself is supposed to be merged with data...

@DzmitryShylovich
Copy link
Contributor

DzmitryShylovich commented Oct 18, 2016

so can you explain why I can access the data defined in the data property of the parent without calling parent.data

it's the actual bug. and u have access only on initial navigation. or may be it's a feature. Need feedback from Victor

@michaelchiche
Copy link
Contributor Author

michaelchiche commented Oct 18, 2016

To my understanding, its the other way around.
Maybe @vsavkin can help us on this one? :)

@olegdunkan
Copy link
Contributor

olegdunkan commented Oct 18, 2016

@michaelchiche I have tried to explain you why data merge is not good idea and it seems to me that it is more likely bug then feature (n^2 to store all data) although for first navigation it is more likely feature. If it is a feature then every navigation along the path have to be accompanied with collection of data.

Let say we have a/b/c/d/e

Let first we navigate to a/b/c/d/e then at 'e' we will have all data (a/b/c/d, e) and it will cost nothing to get it because we go along the 'a', b', .. 'e' and we can preserve resolved data. But what if next navigation will be to a/b/c (upward) (we resolved a,b and c already we only need access to it)? Then to get {a,b,c} we have to keep it in 'c' node in merged form or collect it from a to c and get it to user. It is not necessary in many cases to have data from levels above at every level.
You have all(API) to get it through the parent property, it is your choice to use it or not.

@michaelchiche
Copy link
Contributor Author

michaelchiche commented Oct 18, 2016

@olegdunkan
Copy link
Contributor

olegdunkan commented Oct 18, 2016

@michaelchiche I will try to check it. By the way, if we have the same name of data properties at different levels then how conflicts will be resolved?

{
    path: 'a',
    component:A,
    resolve: {
      part: AResolver 
    },
    children: [
      {
        path: 'b',
        component:B,
        resolve: {
            part: BResolver  
        }
      }
    ]
  }


in B component 
onInit() {
  this.route.data.subscribe(data=> {
  // => data = {part:...}); //from AResolver or BResolver, last??????
}

It is difficult to maintain

@olegdunkan
Copy link
Contributor

olegdunkan commented Oct 18, 2016

@michaelchiche
I have checked it, look at https://github.com/angular/angular/blob/2.1.0/modules/%40angular/router/src/router.ts#L728
these lines say us that router reusing path and do not add checks (CanActivate for routes we have passed).

@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 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants