Opaldes
Opaldes

Reputation: 193

Meteor Collection find()/fetch() working sometimes

I started working with meteor which seems to be good for my use, a problem occurred where I get my documents only 9/10 times. I think I implemented something wrong.

I use Angular 1.5 and Typescript

My collection gets created in the lib folder at /

import { Mongo } from 'meteor/mongo';

export const Locations= new Mongo.Collection('locations');

then the collection gets imported to my service

import {app} from '../../js/lib/app';
import {Locations} from '../../../lib/collections';

export class LocationsService {

    locations: any;

    constructor(){
        console.log('Constructor called');
        this.locations = Locations
                .find({})
                .fetch();
        console.log('documents loaded');
        console.log(this.locations);
    }

    public createLocation(any:any){
        Locations.insert(any);
    }

    public updateLocation(identity:any, modifier:any){
        Locations.update(identity,modifier);
    }

}

app.service('locationsService', LocationsService);

Here are the console.logs from 3 different page refreshes:

enter image description here

enter image description here

enter image description here

It looks like the amount of docs I get is totally random.

Upvotes: 0

Views: 191

Answers (2)

Opaldes
Opaldes

Reputation: 193

My new Service simply subscribes

export class LocationsService {

    locations:any;

    constructor(){
        console.log('Constructor called');
        //Subscribe to a collection//localStorage.getItem('ID')
        Meteor.subscribe('locations', 2223 );
        this.locations = Locations;
        console.log('documents loaded');
    }

    public createLocation(any:any){
        Locations.insert(any);
    }

    public updateLocation(identity:any, modifier:any){
        Locations.update(identity,modifier);
    }

}

app.service('locationsService', LocationsService);

In my controller i simply add the fetching of my documents in the Tracker.

import {app} from '../../js/lib/app';
import {LocationsService} from './LocationsService';
import {Tracker} from 'meteor/tracker';

export class LocationsController {

    static $inject = ['locationsService','$reactive','$scope'];

    public $reactive: any;
    public $scope: any;

    public locations: any[];


    constructor(private locationsService: LocationsService, $reactive:any, $scope:any){
        this.locationsService = locationsService;
        this.$reactive = $reactive;
        this.$scope    = $scope;
        $reactive(this).attach(this.$scope);
        Tracker.autorun(() => {
            //console.log('autorun');
            this.locations = locationsService.locations.find({}).fetch();
            console.log(this.locations)
        });
    }

    public createLocation(location:any){
        console.log('Locations does what it should');
        console.log(location);
        this.locationsService.createLocation(location);
    }

    public updateLocation(location:any, modifier:any){
        this.locationsService.updateLocation(location._id,modifier)
    }

}

app.controller('locationsController', LocationsController);

The only problem I have now is that the modell updates like a charm but not the view when I create new locations. The autorun works and the new location gets saved in my collection but I see it only if I reload. But that one is low priority for me.

Upvotes: 0

Mikkel
Mikkel

Reputation: 7777

Here is some code that will help you. It uses the "resolve" feature of ui-router to hold up loading of the page until data is loaded. In this case there are two things being resolved:

  1. User record
  2. Elders record

The second one needs an "elderid" from users.profile in order to find an elder record.

function config($locationProvider, $urlRouterProvider, $stateProvider) {
      'ngInject';
      $stateProvider
        .state('member.calendar', {
          url: '/calendar',
          template: "<membercalendar></membercalendar>",
          resolve: {
            currentUser: ($q) => {
              var deferred = $q.defer();

              Meteor.autorun(function () {
                if (!Meteor.loggingIn()) {
                  if (Meteor.user() == null) {
                    deferred.reject('AUTH_REQUIRED');
                  } else {
                      deferred.resolve(Meteor.user());
                  }
                }
              });

              return deferred.promise;
            },
            elder: ($q) => {
              var deferred = $q.defer();

              Meteor.autorun(function () {
                if (!Meteor.loggingIn()) {
                  if (Meteor.user() == null) {
                      deferred.reject('AUTH_REQUIRED');
                  } else {
                    deferred.resolve(Elders.find({_id: Meteor.user().profile.elderid}));
                  }
                }
              });

              return deferred.promise;
            }
          }
        });

    }

This works well if you want the data to be loaded fully before the page loads. If you don't mind an asynchronous update to the page, you can use getReactively to make a helper run once the data has resolved. I can give you example code for that too if you like.

Upvotes: 1

Related Questions