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

Aurelia tries to set bindingContext when there is no View #238

Closed
niieani opened this issue Dec 23, 2015 · 10 comments
Closed

Aurelia tries to set bindingContext when there is no View #238

niieani opened this issue Dec 23, 2015 · 10 comments

Comments

@niieani
Copy link
Contributor

niieani commented Dec 23, 2015

I'm doing a Redirect before the view is created, yet Aurelia still tries to execute the binding, which causes an error:

aurelia-templating.js:2702 Uncaught (in promise) TypeError: Cannot set property 'bindingContext' of null
    at Controller.automate (http://localhost:9000/jspm_packages/npm/aurelia-templating@1.0.0-beta.1.0.2/aurelia-templating.js:2702:32)
    at addNextView (http://localhost:9000/jspm_packages/npm/aurelia-templating-router@1.0.0-beta.1.0.3/router-view.js:112:40)

This line throwing the error is here:

this.view.bindingContext = this.viewModel;

It's hard for me to pinpoint the exact source of the problem.

@EisenbergEffect
Copy link
Contributor

Can you create a small, simple reproduction, zip it up and attach it here? along with steps to reproduce the issues. That would help us find the problem.

@fragsalat
Copy link

I guess he's trying the same like me.
I've got a route called logout.
The viewModel has the decorator @noview.
In there's a service call and a new Redirect.

So using the noView on a viewModel seems to be not working.

import {noView} from 'aurelia-framework';
import {Redirect} from 'aurelia-router';

@noView
export class SomeViewModel {
    constructor() {
        // Some service call and redirect
        new Redirect('');
    }
}

@niieani
Copy link
Contributor Author

niieani commented Jan 19, 2016

@EisenbergEffect I'm really sorry but I think I've lost the code that was causing this problem. I'll try to go back in my project's commit history to find it though, but it may take some time before I have the time to do so.
But I think a way to reproduce this is to do a redirect on a parent router in bind() or in a constructor of a ViewModel that's being activated by that router. My code was not using noView like @fragsalat's, however I believe it might be the same problem.

@EisenbergEffect
Copy link
Contributor

Definitely using Redirect in a constructor won't work. The Redirect instance would need to be returned from the canActivate hook, at the earliest.

But currently, the router enforces that all view models that get rendered must have a View. We may be able to change that in the future though.

@niieani
Copy link
Contributor Author

niieani commented Jan 19, 2016

Oh, sorry for the confusion, I wasn't using a Redirect instance, I was running the navigate method on a Router instance, if I remember correctly, in either the activate() or bind() hook. You see, my use case is that:

  • The route for the ViewModel is /route/:id
  • I need to check if :id is not empty or an element of the given :id exists in the database
  • If yes - I allow the activation of the View, pull the data and it gets rendered
  • If no - I need to query the database for the "default" :id and redirect to it (discarding the current view). And here's where the problem started happening - the view was not rendered yet but I was trying to redirect.

@StrahilKazlachev
Copy link
Contributor

Isn't adding a PipelineStep more suitable approach for this scenario? To me this seems similar to the AuthorizeStep example.

@niieani
Copy link
Contributor Author

niieani commented Jan 20, 2016

Can pipeline steps be asynchronous?
Also, this means blocking the rendering until after the query is made,
which is pretty horrible for UX. I prefer to start the query in a Promise
as early as possible (activate()) and do the redirect in a .then, once
I know the result from the database.
On Tue, 19 Jan 2016 at 23:47, StrahilKazlachev notifications@github.com
wrote:

Isn't adding a PipelineStep more suitable approach for this scenario? To
me this seems similar to the AuthorizeStep example.


Reply to this email directly or view it on GitHub
#238 (comment).

@StrahilKazlachev
Copy link
Contributor

Yes, you can return a promise. I don't follow on:

Also, this means blocking the rendering until after the query is made,

Returning a promise in the activate method also delays the rendering.

@niieani
Copy link
Contributor Author

niieani commented Jan 20, 2016

Yes, but you don't need to return the Promise - you can just create it. I
set the Promise as a property on the ViewModel and await it in the
attached() method. This way my View isn't blocking - UX is good, and if a
redirect is needed, it happens.

On Wed, Jan 20, 2016 at 12:09 PM StrahilKazlachev notifications@github.com
wrote:

Yes, you can return a promise. I don't follow on:

Also, this means blocking the rendering until after the query is made,

But returning a promise in the activate method also delays the rendering.


Reply to this email directly or view it on GitHub
#238 (comment).

@EisenbergEffect
Copy link
Contributor

Looks like this was solved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants