cellulosa
cellulosa

Reputation: 489

Handling relationships in meteor-angular

coming from a heavy MySQL and PHP background I can't really get my head over this.

I have a collection of branches with a ManyToOne relation to Restaurants (so there are many branches attached to the same restaurant).

Such relation is defined by the field restaurantId, which stores the id of the object. My branches collection appears as follows:

{
    "_id" : "uH4KbNYxw8cnCEqvk",
    "address" : "1 High Street",
    "loc" : {
        "coordinates" : [ 
            0.0, 
            0.0
        ],
        "type" : "Point"
    },
    "restaurantId" : "dvxZ2NiA3gbevffsk"
}

And of course the restaurants collection

{
    "_id" : "dvxZ2NiA3gbevffsk",
    "name" : "Restaurant name"
}

Now, I'm querying all the branches ordered by proximity using $near, and I can't find a clean way to get the name of the parent restaurants while looping over the branches.

Here is what I did - I mean, it works as it is, but I think performance-wise it has a lot to be improved

// controller
angular.module("MyApp").controller("SearchRestaurantsCtrl",
    function($scope, $stateParams, $meteor){

        $meteor.subscribe('branches');
        $meteor.subscribe('restaurants');

        $scope.branches = $meteor.collection(function() {
            return Branches.find({
                loc: {
                    $near: {
                        $geometry: {
                            type: "Point",
                            coordinates: [ $stateParams.lng, $stateParams.lat]
                        },
                        $maxDistance: 300000
                    }
                }
            });
        });

        $scope.getRestaurant = function(restaurantId) {
            return Restaurants.findOne({
                _id: restaurantId
            });
        };
    }
);

// view
<div ng-repeat="branch in branches">
    <h3>{{getRestaurant(branch.restaurantId).name}}</h3>
    <address>{{branch.address}}</address>
</div>

Upvotes: 1

Views: 154

Answers (1)

cellulosa
cellulosa

Reputation: 489

I ended up using passing both the collection and filtering using angular:

Controller

angular.module("sushisushi24").controller("SearchRestaurantsCtrl",
    function($scope, $stateParams, $meteor){

        $scope.branches = $meteor.collection(Branches).subscribe('branchesAndRestaurants');
        $scope.restaurants = $meteor.collection(Restaurants);
    }
);

Meteor Publish

Meteor.publish('branchesAndRestaurants', function(opts) {

    branches = Branches.find();
    restaurantIds = branches.map(function(branch) { return branch.restaurantId });

    return [
        branches,
        Restaurants.find({_id: {$in: restaurantIds}})
    ];
});

View

<div ng-repeat="branch in branches">
    <div ng-repeat="restaurant in restaurants | filter: {_id:branch.restaurantId}">
        <h3>{{restaurant.name}}</h3>
    </div>
    <address>{{branch.address}}</address>
</div>

Upvotes: 1

Related Questions