Blended assortments in Meteor

I found a helpful tutorial on building an Ionic/Meteor/Angular app and followed it to the point where I removed autopublish and insecure. Now, I'm diving into data publication and subscription in my project:

Inside my Meteor app's lib/collections.js, I have two MongoDB collections:

Players = new Mongo.Collection('players');
Teams = new Mongo.Collection('teams');

A player has an _id and a name, while a team has an _id and an array of exactly two players:

["someplayerId", "someotherPlayerId"]

In the server-side publications defined in server/publications.js, I currently have:

Meteor.publish('players', function () {
  return Players.find({});
});
Meteor.publish('teams', function() {
    return Teams.find({}, {transform: function(doc) {
        var playerOne = Players.findOne({ _id: doc.players[0]._id });
        var playerTwo = Players.findOne({ _id: doc.players[1]._id });

        doc.playerOne = playerOne;
        doc.playerTwo = playerTwo;

        return doc;
        }
    });
});

In my client-side routes configuration in client/routes.js, I subscribe to these publications for one of my states:

.state('tab.settings', {
  url: '/settings',
  views: {
    'tab-settings': {
      templateUrl: 'client/templates/settings.html',
      controller: 'SettingsCtrl as settings',
      resolve: {
        teams() {
          return Meteor.subscribe('teams');
        },
        players() {
          return Meteor.subscribe('players');
        }
      }
    }
  }
});

But when trying to use the teams data in my code, I am struggling to correctly access the compound data.

The following code snippet triggers an error because playerOne and playerTwo variables are undefined:

  this.helpers({
    players: () => {
      return Players.find({});  
    },
    teams: () => {
      return Teams.find({}, {transform: function(doc) {
        var playerOne = Players.findOne({ _id: doc.players[0] });
        var playerTwo = Players.findOne({ _id: doc.players[1] });

        doc.playerOne = playerOne.name;
        doc.playerTwo = playerTwo.name;

        return doc;
        }
      });
    }
  });

In the template file 'client/templates/settings.html', I want to utilize the transformed team documents. How can I achieve this?

Answer №1

It is likely that your subscriptions are not yet prepared for use. My suggestion would be to utilize template-level code to display the team and subsequently render each player within that team. In your publication:

Meteor.publish('teams', function () {
  return Teams.find({}, {
    transform: function (team) {

      // By implementing this, you will gain access to all players in this team.
      team.players = Players.find({
        _id: { $in: team.players }
      }).map(player => player.name);

      return team;
    }
  });
});

The resulting document structure will be:

{
  _id: '1234',
  players: ['Jeff', 'Tim', 'Steve']
}

Then, inside your template, you can proceed as follows.

{{#if Template.subscriptionsReady}}
  {{#each teams}}
    // With the player array now available within the team, you can make use of it.
    {{#each players}}
      {{this}}
    {{/each}}
  {{/each}}
{{/if}}

Answer №2

After some experimentation, I have found a solution to my initial question. On the server side, I created two publications:

Meteor.publish("players", function () {
  return Players.find({});
});
Meteor.publish("teams", function () {
  return Teams.find({});
});

These publications are managed in the router for all subroutes under tabs:

  $stateProvider
    .state('tab', {
      url: '/tab',
      abstract: true,
      templateUrl: 'client/templates/tabs.html',
      resolve: {
        players() {
          return Meteor.subscribe('players');
        },
        teams() {
          return Meteor.subscribe('teams');
        }
      }
    })

This approach replicates the functionality of the autopublish package on the client side, which serves its purpose for now.

Now, on the client side, I can modify data using the following code:

  this.helpers({
    data: () => {
      return Teams.find({}, {transform: function(doc) {
        doc.playerOne = Players.findOne({ _id: doc.players[0]._id });
        doc.playerTwo = Players.findOne({ _id: doc.players[1]._id });
        return doc;
        }
      });
    }
  });

I can then utilize the data variable in my templates like so:

  <ion-item ng-repeat="team in teams.data">
    {{ team.players[0] | player_name }} and {{ team.players[1] | player_name }}
  </ion-item>

The player_name filter is a simple Angular filter defined as follows:

angular
  .module('PLeague')
  .filter('player_name', player_name);

function player_name () {
  return function (player) {
    if (!player) return;
    return player.name;
  };
}

Key changes from the original code include the publications for the Teams collection and the modification of how the client-side code handles Teams by retrieving players using findOne with players[x]._id.

Perhaps this adjustment was what was missing initially.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble showing the material-ui icon on my navigation menu

How can I use Material-UI icons like <AddOutlinedIcon /> in my nav menu without displaying the actual code before the menu name? Do I need to escape the icon code somehow to make it appear correctly? The intended result is to have a + icon displaye ...

Using Javascript or Typescript constants along with WebPack being invoked twice

I am encountering an issue with my constants file: collections.ts import {Mongo} from 'meteor/mongo'; import {Chat, Message} from 'api/models'; export const Chats = new Mongo.Collection<Chat>('chats'); export const Me ...

Node.js and Express: troubleshooting slow page loading issues

Currently, I am following a PluralSight tutorial on Node.Js/Express. However, I am facing an issue with my admin router page as it seems to be loading indefinitely without showing any error messages. This page is supposed to run on localhost:4000. Interest ...

Querying for a specific element within an array of MongoDB objects using PyMongo

When querying for a field in an array using MongoDB, you can use the following syntax: students.find({'name':{$in:['Mark','Jerry']}}) But how would you query if a specific string is in an array within a MongoDB object like t ...

What would be a colloquial method to retrieve the ultimate result from the iterator function?

I've got a rather complex function that describes an iterative process. It goes something like this (I have lots of code not relevant to the question): function* functionName( config: Config, poolSize: number ): Generator<[State, Step], boo ...

Unraveling the mysteries of the spread operator in Javascript

Having trouble finding the right keyword to search for my issue, as I am confused about JavaScript or TypeScript spread operator behavior. I encountered this problem while working on a drag and drop function today, but let me provide a simple example. Imag ...

Can you explain the role of server-side programming in web development?

Recently venturing into the world of web development, I have embarked on creating a web app using Vue/Vuetify. As I delved into ways to load and parse a .csv file, I encountered errors that led me to discover this task should be handled server-side. This ...

Reorganizing Angular 2 modules into separate projects

My goal is to develop portal-like functionality using Angular 2. This will involve creating a base navigation system and global services like authentication, while still allowing other developers to build their own modules that can seamlessly integrate wit ...

Can an input element be used to showcase a chosen image on the screen?

I would like to display the selected image from an input element. Can this be done with a local file, accessing the image on the client side, or do I need to upload it to a server? Here is my React code attempt: I can retrieve the correct file name from t ...

Expanding the Angular UI bootstrap modal to fullscreen

Hey there, I've got a modal with a custom size: var dialog = modal.open({ template: content, size: size, controller:'someController' cont ...

What is the alternative to using document.getElementById?

1) Question 1 Why does the following example work without using "document.getElementById('myId')" and is it acceptable to skip this step? <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Javascript quest ...

The JSON parser is struggling to process a string that consists of an array of objects

When working in my Node.js file route, I encountered an issue while rendering an ejs file with variables passed as a stringified array of objects: let scriptArray = [ { charValue: 'a', encodedValueMain: 'g', }, { charV ...

Creating initial state in Redux Toolkit with data fetched using Apollo's useQuery

Can I use the useQuery hook in a Redux toolkit slice, even though it's typically used only in functional components? Is there a way to achieve this using createAsyncThunk or a similar method? My project employs the MERN stack with MongoDB as the datab ...

Introducing a fresh counter variable inside a for loop

I'm currently working on a project with google-apps-script. My goal is to copy a row multiple times based on the number specified in a certain cell within a spreadsheet. For example, if B2 contains the number 6, I want to duplicate that row 6 times. I ...

Creating a complex user interface in Angular using multiple nested views with the help of Angular

Exploring the nested views functionality of the ui-router plugin has presented me with a challenge that I am struggling to resolve. The problematic code can be accessed at this link: http://jsfiddle.net/3c9h7/1/ var app = angular.module('myApp&apos ...

What is the proper way to use special characters like "<>" in a parameter when sending a request to the server using $.ajax?

Upon submission from the client side, a form is sent to the server using $.ajax: function showSearchResults(searchText, fromSuggestions) { $.ajax({ url: "/Home/Search", data: { searchText: searchText, fromSuggestions: fromSuggestions } ...

Looking to improve MongoDB query performance

I have a query in my MongoDB database and I've already set up the necessary indexes. However, the query is still scanning through all documents in the collection. Here is the query: [ { "$group": { "driverStatus ...

When will the javascript file fire if it has this implementation?

Can someone help me make sense of this jquery snippet? (function( window, undefined ) { //All the JQuery code is included here ... })(window); I'm curious, if a .js file is loaded in a page using the <script> tag, at what point does it ...

Retrieve a specific line of code from a snippet of JavaScript

I am looking to extract a specific line of code from a script that I am receiving via ajax... The line in question is new Date(2010, 10 - 1, 31, 23, 59, 59) found within the following snippet: jQuery(function () { jQuery('#dealCountdown').count ...

What specific blur algorithm is utilized by the Flash platform within their blur filter implementation?

I'm in the process of translating AS3 code to JavaScript, and I've come across an AS3 application that utilizes Flash's built-in Blur Filter Could someone provide insight into the blurring algorithm used by this filter or suggest ways to re ...