Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creation of user profile page with Meteor and Iron Router

I'm building a web app with Meteor and the Iron Router and one of my goals is to build a profile view for the user that's logged in (where he can edit his info) and profile view for all the users (which can be viewed by any person).

The profile view of the user logged in works well, but I'm having problems in creating the user profile view for the other users. When I try to access directly in the browser to some user profile with the url (eg: localhost:3000/users/"id") it renders the data of the user logged in and the url in the browser changes to localhost:3000/users/[object%20Object].

Also the tag with the reference to the is always empty when the page with that info is rendered.

Here is the code related with this problem:

server - publications.js

Meteor.publish('singleUser', function(userId) {
   return Meteor.users.find(userId);
});

router.js

Router.map(function() { 
    this.route('profile', {
        path:'/profile',
        data: function() {return Meteor.user();}
    });

    this.route('user_profile', {
        path: '/users/:_id',
        waitOn: function() {
                return Meteor.subscribe('singleUser', this.params._id);
        },
        data: function() { 
                var findById = Meteor.users.findOne(this.params._id);
                if (typeof findById !== "undefined") {
             Router.go(getProfileUrlById(findById),  {replaceState: true});
                }
        }
    }); 
});

User Profile template

<template name="user_profile">
    <h4>Username</h4>
    <p>{{username}}</p>
    <h4>Email:</h4>
    <p>{{email}}</p>    
</template> 

User Profile Helpers

Template.user_profile.helpers({
     username: function() {return Meteor.user().username},
     email: function() {return Meteor.user().emails[0].address} 
});

Item template

<template name="item">
    </span> <a href="{{profileUrl}}">{{author}}</a>
</template> 

Item Helpers

Template.item.helpers({
    profileUrl: function() {
        var user = Meteor.users.findOne(this.userId, {reactive:false});
        if(user)
            return getProfileUrlById(user);
    }
 });

getProfileUrlById = function(id) {
    return Meteor.absoluteUrl()+'users/' + id;
}

User Profile logged in template

<template name="profile">
    <h4>Username</h4>
    <p>{{username}}</p>
    <h4>Email:</h4>
    <p>{{email}}</p>
</template>

User Profile logged in helpers

Template.profile.helpers({
    username: function() {return Meteor.user().username},
    email: function() {return Meteor.user().emails[0].address}
 });

Am I missing something?

Thanks in advance!

like image 223
swayziak Avatar asked Nov 02 '22 08:11

swayziak


2 Answers

The type of findById that you're getting from Meteor.users.findOne is an Object, and so when it is cast to a string in getProfileUrlById, it ends up being [object Object]. You probably want to pass the userId value from the object to that function, not the object itself.

like image 170
MischaNix Avatar answered Nov 13 '22 15:11

MischaNix


The primary problem seems to be that you're not publishing private data to the user collection for other users (assuming you have the autopublish package uninstalled). Only fields under profile are published by default by Meteor. Your username field for example is not in profile so it will not get published for all users except the one currently logged in.

Secondly, you're overcomplicating route generation. Try generating your route like this:

{{#each users }}
<a href="{{ pathFor 'userAccount' }}">My account</a>
{{/each }}

This will automatically use the _id field as a key, assuming your router.js file looks like this:

Router.map(function () {
  this.route('userAccount', {
    path: '/users/:_id'
  });
});
like image 32
advancingu Avatar answered Nov 13 '22 17:11

advancingu