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

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

Oh wow, sometimes things can be so simple :smiley:
Never occured to me.

If notes don’t live alone and belong to the context of a task (perhaps) you can also consider joining notes to tasks as you join tasks to workspaces

1 Like

You know, thinking more about the MongoDB structure we talked about (about not having embedded documents), I’m not so sure it makes a huge performance difference. Isn’t it worse to have references pointing to different collections, since you now have to make multiple successive DB hits to fetch data (rather than one atomic query)? Not to mention there’s no transactions in Mongo, so you have to implement your own home-grown rollback system in case an update fails.

Update #4

Thanks to your advice. Helped a lot.
Since the concept of joining collections is completely new to me I went with Sanjo’s approach.

So now the data model looks like this:

Moving from two collections (notes & tasks) to only one (entries) ment rewriting quite a few things.
This made me realize how important it is to have a solid data model before you even start coding.

Changes

  1. Got rid of the notes & tasks collections
  2. Added the entries collection
  3. Added chronological order of tasks and notes
  4. Successfully corrected the feature to only show the input-field when a workstream is selected. (Thanks to Sanjo for the tip)

App-Status

Here’s the current Version:
http://workstreams_v4.meteor.com/
(Tested in Chrome only)

What’s next?

  1. User Accounts
    Only played with the standard “accounts” packages so far.
    Building a customized login will be new to me. Probably taking a closer look at the “useraccounts” packages for that.
  2. Cleaning things up (css-stuff) + removing the insecure & autopublish packages.
    Heew… this should be fun.

Big thanks

Overall many thanks to all the advice from you guys.
I know it’s a small & simple app, but I’m quite happy to see it coming together now :smile:

1 Like

I think task and note should be seen as subclasses of entry. I wonder why you needed to rewrite so much. The data model didn’t really change much.

I guess in hindsight you’re right. It just still felt uncomfortable to me to touch code that I already got running. :smiley:

I’m working on the next update and things are coming along fine.

Question

To this I couldn’t find a solution:
When I have a lot of entries attached to a stream, there is a delay when I want to display/render them.

It’s probably easier to understand, when you experience it yourself:

http://workstreams_v5.meteor.com/

Username: admin
Password: admin1234

I’ve set up 4 streams with 10, 25, 50 and 100+ entries attached to them.

  • As you can see up to 50 entries render reasonably fast.
  • But when you click on the stream with 100+ entries, there is a delay of some seconds.

Is there a way around that?

Also I dont really understand why this should be happening.
All the entries are already there on the client, stored in minimongo, right? So why the delay?

Also:
There seems to be a tiny delay for any action. (e.g. checking of tasks)
It’s not much, but a little bit slower than when I work locally.
Is that normal?
My understanding was, that changes (e.g. updates or inserts) should happen instantly on the client and then sync with the server in the background. (Optimistic UI?)

Happy for any kind of help in this. :slight_smile: