I needed to request some markdown text stored in a file from the server and render in a React component. This situation is not well suited to the normal “store in a collection, then publish to the client” approach. After a little bit of head-scratching, I figured out how to combine Meteor Method and React useState() and useEffect() to do this. It’s only 20 lines of code, and I think it’s a pretty generally useful design pattern:
import React, {useEffect, useState} from 'react';
import ReactMarkdownWithHtml from 'react-markdown/with-html';
import PageLayout from '../PageLayout';
import {getTermsAndConditions} from '../../../api/utilities/TermsAndConditions.methods';
const headerPaneTitle = 'Terms and Conditions';
const headerPaneBody = `
Here are the terms and conditions for using RadGrad.
`;
/**
* Student Terms and Conditions Page Processing
*
* The goal of this page is to display the Terms and Conditions, where Terms and Conditions are located in a file
* on the server side, the location of which is indicated via a settings property.
*
* This page provides a simple example of how to display a page in React where its contents must be fetched
* asynchronously from the server side. Normally, we do this via publications and subscriptions, but here is a situation
* where we need some data from the server that is not stored in a Collection!
*
This file has been truncated. show original
The Meteor Method is here. Note that it’s helpful to disable the Optimistic UI stuff:
import {ValidatedMethod} from 'meteor/mdg:validated-method';
import {CallPromiseMixin} from 'meteor/didericis:callpromise-mixin';
/**
* Meteor method used to retrieve the terms and conditions string from a file and return it to the client.
*/
export const getTermsAndConditions = new ValidatedMethod({
name: 'TermsAndConditions.getTermsAndConditions',
mixins: [CallPromiseMixin],
validate: null,
run() {
let terms = '';
if (Meteor.isServer) {
const fileName = Meteor.settings.termsAndConditionsFileName;
if (fileName) {
terms = Assets.getText(fileName);
} else {
terms = 'Terms unknown';
}
}
This file has been truncated. show original
Enjoy!