[Question] Building my first App - general advice for starters needed

Hi Meteorites!

The Situation

After finishing different tutorial-apps, reading a lot and slowly falling in love with Meteor I’ve decided to build my first own app. From idea to concept to final usable product. Something I can use in my day to day job as a frontend dev / webdesigner.

For this I would love to have some general advice.
(Questions at the bottom)

The Idea

At work I mainly do webdesigns/concepts for different projects.
So in the app I need to create:
a) different “workspaces” (or “workstreams”) for different projects,
b) add tasks,
c) add notes & feedback,
d) have some kind of timeline at the end of the project (to see what happened in general)

So basically:
A super simple version of Slack. Plus tasks.

The concept

I’ve made this concept for desktop and mobile, which should make things more clear:
http://tinyurl.com/ot4hr9w
(Created with Balsamiq Mockups - great tool, highly recommend it)

Functionality:
a) You enter new tasks or notes (at the bottom), which are then displayed on a timeline.
b) With the dropdown (at the top) you can chose: Complete Stream, Notes only, Tasks only, to filter the

stream.

Apart from that:
Just simple user accounts, no roles, no permissions, no backend, or sharing of workspaces between users.

The Questions

  1. I’m not sure exactely where to best start. Build the layout in html & css first and then apply the functionality? Implement the workspaces next? Or start with building a simple task-list first and work from there? Does it even matter? How would you approach such a thing?
  2. Are there any pitfalls you can see? Something thats terribly tricky and I should watch out for?
  3. A bit vague, I know: How long would a professional Meteor developer (you?) need to build this?

Closing thoughts

Yup, thats it.
Any thoughts and or advice is highly appreciated. I’m eager to start and am totally happy to have joined this community. Looking forward to work with you all. :slight_smile:

Cheers

4 Likes

First, welcome to the Meteor community!

Second:

“A journey of a thousand miles begins with a single step.” - Laozi

But in all seriousness I think the idea of building an entire app from nothing can be a bit daunting. Since you said you are a frontend engineer I would start with building the frontend/ui because that is presumably what you are the most comfortable with. After you have the UI up and static you can start applying the most basic functionality to it which for the most part will be just more frontend javascript. Eventually there will be a point when you can’t do anything more without adding some server side functionality. You can do this part incrementally as you need it (I would put together a basic idea of how you want your collections to be defined as well as server side file structure to help maintain a clean code base first but that’s just me). Then if you continue to build it I think you will realize that most things aren’t as hard as they seem at first.

tl;dr: build what you’re comfortable with first then fill in whats left.

Just my opinion though, everyone has different methods. :slight_smile:

1 Like

To address your first question about how to get started :
Personally I start at the Schema = Data Model for the app. I make a list of Collections and their fields and field types. Simple Schema package is helpful for this process but is not necessary. In fact you can just do it on paper, very similar to mocking up a UI, it’s just a draft of your database.
Most likely it’s going to change, so I do my best and then move on to coding the UI, then I’ll realize I need additional fields on a Collection or perhaps two separate Collections should really be a single Collection, etc. So it becomes an iterative process.
I find that a well suited database design makes the UI coding really fast and intuitive, so if at a certain point it becomes extremely challenging to code some feature I’ll reconsider the Schema and often times manipulate it to better serve the needs of the application.

You’ve done a good job of clearly describing your needs here. So if it were me I would start by thinking how each of these items would fit into the Database and relate to each other, and then think about what kinds of server Methods will be needed to interact with the data.

good luck!

1 Like

Go to the official MongoDB site and do a lot of reading on different data models (one-to-many, many-to-many, etc). MongoDB is so different from traditional relational databases. If you come from a relDB past, you’ll have to rethink how you want to structure your data, assuming you’ll be using MongoDB.

I can recommend http://asana.com as a product that already does what you want to build. Maybe helpful as inspiration or even a good alternative until you have built your own tool :wink:

I’m not sure exactely where to best start. Build the layout in html & css first and then apply the functionality? Implement the workspaces next? Or start with building a simple task-list first and work from there? Does it even matter? How would you approach such a thing?

You can start with a minimum viable product. Build the essential features first and enhance them with time. I think starting with UI design first is a good idea because it’s visual and you get a better idea what is needed I think. Wireframes are your friend :wink: Or copy an existing tool like Asana :smiley:

Are there any pitfalls you can see? Something thats terribly tricky and I should watch out for?

My oracle doesn’t show anything, sorry :smiley:

A bit vague, I know: How long would a professional Meteor developer (you?) need to build this?

Depends on the feature scope (the details). I think it doesn’t really matter. Take your time. You can take Asana as a fully executed product for this idea :wink: It has a lot of nice detail features that make it a great product. And they still work on it (since 2008).

Since someone brought up wireframes…

Balsamiq is really fantastic. Affordable, and available as a desktop app or a SaaS.

1 Like

Hey everyone,

thanks for your encouraging repliesand the super friendly welcome! :slight_smile:

Update # 1

Following your advice I’ve decided to walk this path:

  1. Build the static version first
  2. Learn some more about MongoDB data models
    (thanks captsaltyjack, the MongoDB Docs already made a lot of things more clrea to me)
  3. Draw out the data-model
    (this still feels new to me, but at the moment I’m thinking about an “embedded data model” with the lists as the main documents, and note & tasks as embedded sub-documents. <- hope what I just wrote made sense :smiley: )
  4. Implement functionality: Add new list
  5. Implement functionality: Add tasks to a list
  6. Implement functionality: Add notes to a list
  7. Login and accounts-stuff

App-Status

I could find some time to work on the static version today.
Here’s the result so far:
workstreams.meteor.com

I focused on the static layout for desktop and mobile + some animations first.
Obviously needs some work, but hey I’m getting somewhere :slight_smile:
Oh, also: Only tested in Chrome.

Hey Sanjo,

@asana:
I agree, asana ist totally great. But for some reason i could never integrate it in my workflow. Really no clue why.

@minimum viable product first:
Ah yes, great, i like this. Will definitely keep it in mind. Thanks :slight_smile:

Thanks a ton for this, man! Data-modeling was exactely where I felt most confused. (Didn’t even know the phrase “data-modeling”) :smiley: Anyway, many thanks!

1 Like

Happy to help! :slight_smile: Good luck

1 Like

Hey khamoud,

just wanted to leave a quick thanks to you. Building the static version first and focus on functionality later feels right to me.

build what you’re comfortable with first then fill in whats left

I’ll keep that in mind :slight_smile:

1 Like

Hey looshi,
thanks so much for your help. Collections feel kinda daunting to me still. Its this magical, complicated beast, that I’m just slowly getting to know better. :smiley:
But making a mockup of the data-model is a fantastic idea. Never occured to me. Will definitely do that!!

1 Like

Update #2

Okay, I could find some time to move forward.

  1. I’ve sketched out the data model for my app:

  2. I’ve created my workstreams-collection and added the functionality to…
    2.1 add strams (via.insert())
    2.2 remove streams (via .remove())
    2.3 select a stream (via Session.set / Session.get)

  3. Then I’ve spend some time on Animations in Meteor.
    3.1 I could successfully implement the “fly-in” effect, when a stream is created
    3.2 I could not do the same for a fly-out effect on remove :frowning: :frowning:
    Overall Animations in Meteor still feel strange and complicated to me.

App-Status

This was the original concept:
http://tinyurl.com/ot4hr9w

And here’s the current Version:
http://workstreams_v2.meteor.com/
(Tested in Chrome only)

What’s next?

Next thing would be the ability to add tasks to a specific stream.
At the moment I have no clue how to insert embedded sub-documents into an existing document. I’ll see what I can find on the topic. But if anyone can point me in the right direction, I’ll happily go there. :slight_smile:

Stop there! :smile:

Don’t do embedded documents because Meteor’s reactivity model works best with top level documents.

Therefore, create separate collections for your notes and tasks, and reference the workstream’s id in them.

Also, don’t use object id’s because most meteor packages (especially the core accounts package) assumes string id’s therefore you’ll sooner or later have some string id’s in your database. Because of that, you’ll want to keep it consistent, so use string id’s with your collections as well.

Now you’ll begin scratching your head about how to join or reference the related notes and tasks with their parent workstreams.

There are multiple ways of doing this and reading through https://www.discovermeteor.com/blog/reactive-joins-in-meteor/ and in fact, read through the complete blog at one go without thinking too much about it. It may whirl your head, but will leave some concepts imprinted in your memory.

I’d also suggest getting a copy of the discover meteor book which is the definitive guide for meteor beginners.

After that, you might want to check out these packages from atmosphere:

  • aldeed:collection2
  • dburles:collection-helpers
  • matb33:collection-hooks
  • reywood:publish-composite
  • tmeasday:publish-counts

for all things collections and publishing for them.

2 Likes

Interesting, can you elaborate on this? MongoDB is focused heavily on embedded documents. Why does this not work well with Meteor?

Mongodb is not focused on embedded documents. It is one of the strategies you can use. ref: http://docs.mongodb.org/manual/core/data-models/

But meteor does have to make some decisions in order to provide the same database api on both client and server and for providing magical reactivity. A major choice is tracking top level documents to compute diffs.

That’s why, embedding documents is not generally advised where the embedded content is to be updated reactively which, a notes/tasks context should be.

Also, with mongodb 2.x versions, documents that grow (by addition of embedded documents into an array within a parent document) indefinitely (as in notes/tasks) http://docs.mongodb.org/manual/core/data-model-operations/#document-growth has performance implications.

1 Like

Where did you read/learn about this? Or did you run tests yourself? So you’re saying that a document like the one below is not good in Meteor? Because reactivity has to work harder to look for updates?

{
  name: 'Thing 1',
  locations: [
    {
      sector: 'A',
      owners: ['PD', 'TY']
    }
  ]
}

Please have a look at the official docs https://github.com/meteor/meteor/blob/devel/packages/ddp/DDP.md and the meteorhacks article https://meteorhacks.com/understanding-mergebox for reference

DDP sends over added/removed/changed messages including the _id of the document. In mongo world, only the top level contains an _id,

Therefore if you change your doc from

{
  name: 'Thing 1',
  locations: [
    {
      sector: 'A',
      owners: ['PD', 'TY']
    }
  ]
}

to

{
  name: 'Thing 1',
  locations: [
    {
      sector: 'A',
      owners: ['PD', 'TY', 'XY']
    }
  ]
}

It will count as a changed event on the subscription, therefore the whole document will cause a recomputation. There are times dom diffing can be clever enough to compute the actual difference, there are times it can’t. But the subscription has to compare the complete document before/after in any case. This is a performance bottleneck as well as unnecessary recomputations.

1 Like

Update #3

First off, thanks serkandurusoy for the new insights. :smile:

So first off I’ve changed the data model like so:

Avoiding embedded documents for now felt easier to me and I could make really good progress.

Changes

This is what I could achieve thus far:

  1. Add & remove notes (via .insert() / .remove())
  2. Add & remove tasks (via .insert() / .remove())
  3. Mark tasks as completed (via .update())
  4. Add notes OR tasks depending on the choice made in the select-field (bottom right)
  5. Insert-Animation for new notes & tasks
  6. Only show the add-tasks/notes input field when…
    6.1 …a workstream is selected and…
    6.2 …at least 1 workstream exists.
  7. Attatch the correct workstream id to new notes/tasks
  8. Only display notes/tasks for the selected workstream
  9. Filter (top left) between "full stream, “notes only” & “tasks only”
  10. Only show the Filter, when a stream is selected

Overall I got a much better understanding on Sessions in Meteor, and how to use them.
Feels really great! :smile:

App-Status

This was the original concept:
http://tinyurl.com/ot4hr9w4

And here’s the current Version:
http://workstreams_v3.meteor.com/
(Tested in Chrome only)

Questions

Some things I’ve stumbled over:

  1. I only show the input-field when a workstream is selected. I do so by using a Session.
    But when I have selected a stream and then just delete every stream, the session is still there.
    So the input field still shows.
    My guess is: I have to somehow “kill” the session in this case?

  2. Currently I display my notes & tasks like so:

WIth two separate #each blocks:

{{#each tasks}}
    {{> task}}
{{/each}}
{{#each notes}}
    {{> note}}
{{/each}}

Of course now notes & tasks wont “mix”.
And I’m not sure how to approach this.
Help is appreciated. :smile:

  1. Show input when session.currentWorkspaceId is set to an ID
  2. When the selected workspace is deleted, also set session.currentWorkspaceId to null

Of course now notes & tasks wont “mix”.

You can put tasks and notes in one collection and add a type field that has either the value “task” or “note”.

1 Like