How to use the Meteor-template

15 Aug 2020

NOTE: This was written for my teammates in a 24 hour hackathon, and it was written FAST. Grammar may not be the best, and some sections might look funky, but we call this character :) Edits coming soon! Please excuse for now.

Much love,

-A

Here are some basic functions of the template to get you up and running. We will get through how to add a page, access it, request data fromt he user, add it to the database, and then retrieve it.

To display data:

To list data, you need to gather data from the user through a form. We will create a page that asks the user for certain data in a certain format and store it in a database. We will format the data through “Schemas”. Example can be found on IMPORTS > UI > PAGES > ADD PAGE. Its way easier to copy paste code and modify as needed.

Lets add a single page:

Lets start by adding the page + button to your site.

Lets add a new page in the PAGES directory.

Next we will give this new page a url

import AddProfile from '../pages/AddProfile';
<ProtectedRoute path="/add" component={AddStuff}/>

and paste it again right underneath it so it looks like this

<Route exact path="/" component={Landing}/>
<Route path="/signin" component={Signin}/>
<Route path="/signup" component={Signup}/>
<ProtectedRoute path="/list" component={ListStuff}/>
<ProtectedRoute path="/add" component={AddStuff}/>
<ProtectedRoute path="/add" component={AddStuff}/>
<ProtectedRoute path="/edit/:_id" component={EditStuff}/>
<AdminProtectedRoute path="/admin" component={ListStuffAdmin}/>
<ProtectedRoute path="/signout" component={Signout}/>
<ProtectedRoute path="/AddProfile" component={AddProfile}/>

NEXT: Lets create a button in the top nav bar to access our new page

Your new entry should look like

<Menu.Item as={NavLink} activeClassName="active" exact to="/addProfile" key='addProfile'>Add Profile</Menu.Item>,

Check to make sure that it shows up on the website, and leads to the exact same page as the Add Stuff button

Adding a list page, where we display something from a database! (eventually)

With a MongoDB data base, info is stored in “Collections”.

class ListProfile extends React.Component {
...
...
ListProfile.propTypes = {
...
...
})(ListProfile);

Then we add to the App.jsx route and make a button for it. ON your website, it should display a page identical to the List Stuff, because its pulling data from the same collection. Refer to how to do that up top! Double check your site to make sure its working

Great! Now, lets make a new collection (its where mongodb stores data!) and add things to it.

class ProfilesCollection {
...
...
this.name = 'ProfilesCollection';
...
...
export const Profiles = new ProfilesCollection();

For simplicity purpose, it will take in the exact same parameters as the original StuffsCollection. We will change this later

Publications

NEXT: Go to IMPORTS > STARTUP > SERVER > Publications.js We will add function here that will return things from the Profiles collection that are associated with the logged in user

import { Profiles } from '../../api/stuff/Profile';
Meteor.publish(Stuffs.userPublicationName, function () {
  if (this.userId) {
    const username = Meteor.users.findOne(this.userId).username;
    return Stuffs.collection.find({ owner: username });
  }
  return this.ready();
});

Meteor.publish(Stuffs.userPublicationName, function () {
  if (this.userId) {
    const username = Meteor.users.findOne(this.userId).username;
    return Stuffs.collection.find({ owner: username });
  }
  return this.ready();
});
Meteor.publish(Profiles.userPublicationName, function () {
  if (this.userId) {
    const username = Meteor.users.findOne(this.userId).username;
    return Profiles.collection.find({ owner: username });
  }
  return this.ready();
});

Change the code so it saves to your new collection

import { Profiles } from '../../api/stuff/Profile';
Stuffs.collection.insert({ name, quantity, condition, owner },

to submitting to the Profiles collection.

Profiles.collection.insert({ name, quantity, condition, owner },

Lets check our work. If you go to the “Add Profile” page of your website and create a submission, you should get an alert saying stuff was added, but it would not show up on the List Profiles page beacause we havent linked it yet

Lets do that now

Showing your profile data. This is a two part thing. PART 1.

Lets create a component for displaying user data. Imagine this whole thing as a function definition. We will pass in a user into this function, and get their name, and other stuff from it. In this case, we will put their data in a table

The

this.props.stuff.name

will take whatever is passed into this function “stuff”, and try to access the “.name” property of it

class ProfileData extends React.Component {
...
...
ProfileData.propTypes = {
...
...
export default withRouter(ProfileData);

We will later be using a map function. Map is kinda like a super smart loop, it takes an array of elements and a function, and then performs that function on every element of that array. In our case, lets say the user makes a bunch of profiles (we shouldnt allow them this, but for the sake of this example we will!). We will pass this array of profiles to the map function, and the function will store each profile into a row of a table.

PART 2

Now that we desiganted how we want the table displayed,

import { Profiles } from '../../api/stuff/Profile';
export default withTracker(() => {
  // Get access to Stuff documents.
  const subscription = Meteor.subscribe(Profiles.userPublicationName);
  return {
    stuffs: Profiles.collection.find({}).fetch(),
    ready: subscription.ready(),
  };
})(ListProfile);

{this.props.stuffs.map((stuff) => <StuffItem key={stuff._id} stuff={stuff} />)}

to

{this.props.stuffs.map((stuff) => <ProfileData key={stuff._id} stuff={stuff} />)}

The List Profile page on your site should list your new profile!

PUSHING AND PULLING FROM DATABASE

How to request specific data

please note that file names might not be exactly the same so be careful

const formSchema = new SimpleSchema({
  name: String,
  bio: String,
  condition: {
    type: String,
    allowedValues: ['excellent', 'good', 'fair', 'poor'],
    defaultValue: 'good',
  },
});
submit(data, formRef) {
    const { name, bio, condition } = data;
    const owner = Meteor.user().username;
    Profile.collection.insert({ name, bio, condition, owner },
<AutoForm ref={ref => { fRef = ref; }} schema={bridge} onSubmit={data => this.submit(data, fRef)} >
              <Segment>
                <TextField name='name'/>
                <TextField name='bio'/>
                <SelectField name='condition'/>
                <SubmitField value='Submit'/>
                <ErrorsField/>

Lets go to the ProfileItems component and tell the component to pull the “bio” from our user profile Notice how we removed the quantity and replaced it with bio

class ProfileItems extends React.Component {
  render() {
    return (
        <Table.Row>
          <Table.Cell>{this.props.stuff.name}</Table.Cell>
          <Table.Cell>{this.props.stuff.bio}</Table.Cell>
          <Table.Cell>{this.props.stuff.condition}</Table.Cell>
          <Table.Cell>
            <Link to={`/edit/${this.props.stuff._id}`}>Edit</Link>
          </Table.Cell>
        </Table.Row>
    );
  }
}

Now the “List profiles” will display your “bio” entry, but not the quantity.

Finally, update the Schema in the IMPORTS > API > STUFF > Profiles to include the updated field