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

this.collection is empty on client side code when initial page render is on server #399

Open
demircancelebi opened this issue Sep 15, 2014 · 22 comments

Comments

@demircancelebi
Copy link

Hi,
I am developing an app with rendr and I am showing some search results in my list.hbs page. It looks like this:

{{# if models.length }}
  {{# each models }}
    {{ view 'listing/list-single' model=this }}
  {{/ each }}
{{/ if }} 

and let's say my listing/list-single.hbs page looks like this:

<h2>{{ title }}</h2>
<p>{{ description }}</p>

in the list-single.js file, I cannot access this.model in client side code if the initial page render is on server. I mean, I can access it in getTemplateData function, but cannot access it in postRender. I can also access this.model if the page is rendered on client, so I think something is broken here.

@bigethan
Copy link
Contributor

No 100% sure but give this a try:

{{ view 'listing/list-single' _model=this }}

@mikepuerto
Copy link

I believe you would actually want to do something like:

{{#if _collection.length}}
  {{#each _collection.models}}
    {{ view 'listing/list-single' model=this }}
  {{/each}}
{{/if}} 

models is just an array of standard objects. _collection is an actual instance of the collection with the models you want to pass to your subviews..

@demircancelebi
Copy link
Author

Thanks to both of you, @bigethan and @mikepuerto . Neither of your solutions solved the issue. I suspect this issue arose when a view is called from another view. I also have another page where I show a single listing, and I can access this.model in both server and client on that page. I still cannot access this.model in list.hbs though if the initial page render is on server. (I can access it in my 2nd search, when rendering takes place in the client)

@mikepuerto
Copy link

That's odd. I am actually doing this exact same thing and it works like a charm. Is it actually rendering the subviews? I have actually seen this issue before where it worked in one place and not another... turned out to be error on my part though... What version are you using?

@demircancelebi
Copy link
Author

this is the version I am using: git://github.com/rendrjs/rendr.git#c599674a87f9044da959d5f2381147f5ce95aebe. What is yours?

@demircancelebi
Copy link
Author

My further examination showed that I can access the attributes of this.model in postRender when I fetch a model in controller and pass it to view, but when I fetch a collection in controller and pass that collection to view, I can see the rendered results on page, but this.collection seems to be empty in client side code. (it is not empty in server side code though)

To summarize this issue, it looks like this.collection is an empty collection in client side code when initial page render is on server side. Don't you have the same issue @mikepuerto @bigethan ? And if not, what is the version you are using?

@demircancelebi demircancelebi changed the title cannot access this.model on client side code when initial page render is on server this.collection is empty on client side code when initial page render is on server Sep 24, 2014
@demircancelebi
Copy link
Author

Don't you have the same issue? @saponifi3d and @sarchila, you might have some ideas about this one maybe?

@sarchila
Copy link
Contributor

Try passing the model_name into the view helper as well. Is the model a Listing model? If so, try

{{ view 'listing/list-single' model=this model_name='Listing' }}

@demircancelebi
Copy link
Author

Well, it turns out that problem is not about the templates or the loop. I can summarize it as:
this.collection is an empty collection in client side code when initial page render is on server side.. So, when I log this.collection in getTemplateData, I can see the collection in terminal and it passes to templates as expected. I log it again in postRender, and it is empty. This problem only occurs when initial page render is on server though. When I come from another page, I can access this.collection in both getTemplateData and postRender.

@sarchila
Copy link
Contributor

Tried to reproduce this, but I am not seeing the symptoms that you describe here. For reference, though, I am using the newest version of Rendr:
git://github.com/rendrjs/rendr.git#43262635f6c82a888598ebb1ce78af86b803678e

It might be that this is fixed by the newer version, or that I am not able to reproduce the issue accurately.

@mikepuerto
Copy link

when I ran into this issue here #390 - I ended up having to go with a different approach being that the amount of help here is scarce. Can't even get @spikebrehm to join any conversation anymore. I've gotta be honest, if there were another, more stable framework... I'd switch in a heartbeat instead of putting all the tim and energy into making changes to the code that they will likely not except a pull request for anyway... -mike (frustrated).

@demircancelebi
Copy link
Author

@sarchila I still have the same issue at that version. @mikepuerto Although I think they would accept a PR which fixes this issue, I feel exactly the same about a more stable framework (which is non-existent AFAIK at the moment).

@saponifi3d
Copy link
Contributor

i think the this scope will be a bit weird in this context. https://github.com/rendrjs/rendr-handlebars/blob/master/shared/helpers.js#L82 sets the scope of the each helper to be a modified version of a model's attributes to include _app and other oddities.

I made a forEach helper that allows me to pass a key and value so i can iterate objects or models as a whole. @sarchila is also correct in that you'll need to pass a model_name for client-side routing to work correctly as the step where rendr grabs the model from the model store it needs to know what model it's trying to grab, not just the id.

extra note: let me know what are some of the biggest bugs you guys are running into, and i'm going to start devoting more of my time to fixing those bugs and updating the documentation of rendr. hopefully this will be getting a lot more stable quickly!

@saponifi3d
Copy link
Contributor

@demircancelebi - i'm working on a PR to rendr-handlebars to add the forEach helper I wrote.

Are there any additional helpers you think might be good to have for everyone?

@demircancelebi
Copy link
Author

Hey,
As I mentioned in later posts in this thread, main issue seems to be not about each helper. My problem is that this.collection is an empty collection in client side code when initial page render is on server side. It only happens when initial page is rendered on server. this.collection is accessible in server side code, so it passes through getTemplateData to .hbs template, but it is empty in postRender or any other function triggered by a user action for that matter.
Same kinda logic works fine with this.model though.
(@saponifi3d, I also saw that you work at Change.org, I am not sure if you do not see the bug that I see, - maybe it has something to do with my default UI language (Turkish) -, but your project pages keeps refreshing itself. You can send me an email if you cannot reproduce.)

@saponifi3d
Copy link
Contributor

interesting that it works in this.model but not this.collection - i think the problem might be with the hydration step here: https://github.com/rendrjs/rendr/blob/master/shared/base/view.js#L482

Which is something i noticed in my last commit to Rendr. For some reason it's never actually doing the creation of a collection if it's passed a json object or something - which might make it so it's not passing through to the template data correctly.

I'll take a gander at the code and see if i can't reproduce / fix this bug for ya! (if nothing else, i'll fix it so it will always at least return a collection).

@sarchila
Copy link
Contributor

@demircancelebi I thought the way @por framed this issue (#350) was super helpful because he demonstrated how to reproduce the issue on the 00_simple example app from this repo.

If you have some time, would you be able to give a couple of steps on how to reproduce this on that sample app, for instance? I've been trying with no luck to reproduce this issue (been trying with a view and a subview that had a collection passed in).

@demircancelebi
Copy link
Author

Ok, I will do that in the next 24 hours :)

@azriel46d
Copy link

Has anything been done on this?

I have the same issue where models generated on the server are not bound to their view on the client side.
This is the scenario:

The builder view i have has a model which contains a list of models for its children similar to the following json

{
"_id": "01234567",
"title" : "My Model",
"elements": {
"12abc213": { "paramA" : "xxxx", "paramB" : "xxxx",  "modelToUse" : "modelA" },
"798xzv78": { "paramA" : "xxxx", "paramB" : "xxxx",  "modelToUse" : "modelB" }
}

now in the builder.getTemplateData' i'm going through the elements and creating the appropriate models according the elements and bound to the particular element with amodel` key (and i even do a model.store()). the using the templates i have something as follows

{{#if elements}}
            {{#each elements}}
                {{view 'some/view/path' model=model}} 
            {{/each}}
    {{/if}}

however on the client side, these models are not found in the modelStore nor are they attached to the view

---EDIT
I tried to move it up to the controller and created a collection from the nodes, on the server the collection and its models is available in the view, whilst on the client side the view's model is undefined .However this time they are available in the model store

---EDIT 2
Still using the collection i finally managed and the key to it was to make the collection hold polymorphic models.

@saponifi3d
Copy link
Contributor

@demircancelebi @azriel46d and @mikepuerto

do you have the idAttribute set to _id on the model?

if so you should only need to do view 'some/view/path' model=model model_name="ModelName" - it needs both an id and a model_name to re-create an instance of the model (or grab it from the store).

My guess is that it just needs to be able to grab the instance from the store or rebuild it with the constructor, and those two things are requirements for doing that.

@roelvanhintum
Copy link

Is there a solution for this issue? The conversation has died, but the problem remains. I'm running into the same issue.

edit: Turns out that i was overriding the parse function on the collection instead of using the jsonKey. Now the collection is parsed without any problem.

@roelvanhintum
Copy link

It looks like this bug isn't a rendr bug at all. In my case it was poor coding on my end. Maybe it is time to close this with the note to check what code is overridden in.

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

7 participants