4

The github presentation of minimongo states it as

Client-side mongo database with server sync over http

There is a also a minimongo-standalone providing a minimongo.min.js which states :

You could also just download the minimongo.min.js, place it on your server, and reference it in your source.

For browsers

<script src="/js/minimongo.min.js"></script>

I previously used d3.js which is packaged in a way so the .js file works both in web-browsers as a lib and on nodes as a npm packages.

So I tried locally with my newly downloaded minimongo.js to build a classic webpage with indexeddb in Chrome as I would do with D3.js. It gives something like that (jsfiddle) :

<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>MiniMongo</title>
    <script src="https://rawgit.com/rurri/minimongo-standalone/master/minimongo.min.js"></script>
    <!-- https://github.com/rurri/minimongo-standalone/blob/master/minimongo.min.js -->
  </head>
  <body></body>
  <script>
    // Require minimongo
    var minimongo = require("minimongo");
    var LocalDb = minimongo.MemoryDb;
    // Create local db (in memory database with no backing)
    db = new LocalDb();
    // Add a collection to the database
    db.addCollection("animals");
    doc = { species: "dog", name: "Bingo" };
    // Always use upsert for both inserts and modifies
    db.animals.upsert(doc, function() {
      // Query dog (with no query options beyond a selector)
      db.animals.findOne({
        species: "dog"
      }, {}, function(res) {
        console.log("Dog's name is: " + res.name);
      });
    });

  </script>
</html>

It returns the errors :

Uncaught ReferenceError: _ is not defined
    at minimongo.min.js:1
    at minimongo.min.js:3
Uncaught ReferenceError: require is not defined
    at (index):5911
Uncaught ReferenceError: _ is not defined
    at (index):91
    at window.onload ((index):5889)

What am I missing or misunderstanding ? How to make it work if possible ?

Josh
  • 17,834
  • 7
  • 50
  • 68
Hugo LOPEZ
  • 605
  • 8
  • 21

2 Answers2

4

A few things

1. Dependencies

If you read the README.MD of minimongo-standalone, it says

Requirements

underscore, async

So you will need to include both those libraries on your page before the minimongo script tag.

<head>
  <script src="https://link/to/underscore.js"></script>
  <script src="https://link/to/async.js"></script>
  <script src="https://rawgit.com/rurri/minimongo-standalone/master/minimongo.min.js"></script>

It's important to mention that you need to get the browser versions of these libraries. It seems that async don't use a Universal Module Definition (UMD) and so provide separate files for different targets.


2. Require

The function require doesn't exist unless you are using browserify or another commonJS module loading framework.

I haven't checked async or underscore, but most libraries will fallback to ordinary globals in the browser if a module system isn't present.

After including the three script tags you should be able to access minimongo-standalone's exported symbols globally


3. minimongo-standalone has a very different API to minimongo

A frustrating point; minimongo-standalone implements the Meteor wrappers around minimongo, and then renames them again. Meaning that any minimongo or Meteor code is not directly transferable.

The good part is that the API is a great deal simpler. The equivalent code for your example would be

// Create collection
var animals = new LocalCollection('animals');
// Insert/update a document

var doc = { species: "dog", name: "Bingo" };
animals.upsert('dog', doc);

// Fetch document and log
var myDog = animals.findOne({ species: "dog" });
console.log("Dog's name is: " + myDog.name);
coagmano
  • 5,542
  • 1
  • 28
  • 41
  • I used cdnjs.org to load the dependencies. It doesn't seems to work : https://jsfiddle.net/7fehe9ey/7/ . It's likely I misunderstood "client side" as "in browser" but it's not. It actually fullty requires a nodejs environment so to load modules via `require()`. – Hugo LOPEZ Feb 22 '18 at 09:10
  • Oh I missed the require error! Sorry. It's both. You need the deps and can't use require as that is a browserify method – coagmano Feb 22 '18 at 09:47
  • I did `npm install minimongo underscore async; npm install -g browserify; echo "{js-only code sample from satckoverflow question above ⬆️}" > ./app.js; browserify ./app.js -o ./bundle.js;`. It results in a 800Kb `./bundle.js` file which works **as a black box** in jsfiddle https://jsfiddle.net/7fehe9ey/8/ , but I cannot write js code in my index.html page that will work with indexeddb. – Hugo LOPEZ Feb 22 '18 at 16:04
  • Ok, I got it. Not cost efficient but I got it. I will add my anwser below but I expect it to be integrated to your answer so you get full credit as you indeed unlocked this issue. – Hugo LOPEZ Feb 22 '18 at 16:18
  • Thanks Fred! Are there more code samples for the standalone version? I can't seem to find anything on it. – Captain Fantastic Feb 28 '18 at 03:13
  • 2
    I found a similar MongoDB wrapper, that seems to work much better, and has better documentation: ZangoDB: https://github.com/erikolson186/zangodb – Captain Fantastic Feb 28 '18 at 03:31
  • It is only 166 Kb – Captain Fantastic Feb 28 '18 at 04:02
  • 1
    @NeedleNoseNeddy, if you have some mastery or correct knoledge of ZangoDB, consider writing an answer on this case study where we can compare approaches : https://stackoverflow.com/questions/48890649/ – Hugo LOPEZ Feb 28 '18 at 15:01
1

@Fred_Stark : you are encouraged to integrate this into your answer.

Short: works but super heavy (800kb!). https://jsfiddle.net/7fehe9ey/9/ . Use something else!

Initial code

/* **************************************************************** */
/* THIS WILL GO TO BUNDLE ***************************************** */
// Require minimongo
var minimongo = require('minimongo');
var LocalDb = minimongo.MemoryDb;
// Create local db (in memory database with no backing)
db = new LocalDb();

/* **************************************************************** */
/* THIS WILL GO TO INDEX.HTML ************************************* */
// Add a collection to the database
db.addCollection("animals");
doc = { species: "dog", name: "Bingo" };
// Always use upsert for both inserts and modifies
db.animals.upsert(doc, function() {
  // Query dog (with no query options beyond a selector)
  db.animals.findOne({
    species: "dog"
  }, {}, function(res) {
    console.log("Dog's name is: " + res.name);
  });
});

Bundles up

npm install minimongo underscore async
npm install -g browserify
echo "var minimongo=require('minimongo');var LocalDb=minimongo.MemoryDb;db=new LocalDb();" > ./app.js
browserify ./app.js -o ./bundle.js

It results in a 800Kb ./bundle.js file which works as a black box in jsfiddle jsfiddle.net/7fehe9ey/8

HTML-JS

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>MiniMongo</title>
    <!-- ======================================================= -->
    <!-- ======================================================= -->
    <script src="./js/bundle.js"></script><!--================== -->
    <!-- ======================================================= -->
    <!-- ======================================================= -->
  </head>
  <body>
</body>
    <script>
    // Require minimongo
    // var minimongo = require('minimongo');
    // var LocalDb = minimongo.MemoryDb;
    // Create local db (in memory database with no backing)
    // db = new LocalDb();
    // Add a collection to the database
    db.addCollection("animals");
    doc = { species: "Cat", name: "Cingo" };
    // Always use upsert for both inserts and modifies
    db.animals.upsert(doc, function() {
      // Query dog (with no query options beyond a selector)
      db.animals.findOne({
        species: "Cat"
      }, {}, function(res) {
        console.log("Cat's name is: " + res.name);
      });
    });

    </script>
</html>

Returns

Console returns :

Cat's name is: Cingo

Hugo LOPEZ
  • 605
  • 8
  • 21
  • I still think this can be done without bundling. I'll take another look – coagmano Feb 24 '18 at 00:10
  • Okay, looking at jsfiddle.net/7fehe9ey/7 you've included the `requirejs`/AMD version of async that requires bundling. Really, all of these packages should just use UMD and then you wouldn't need different bundles for different bundlers and the browser. Swap it out for one like: `https://cdn.jsdelivr.net/npm/async@2.6.0/dist/async.min.js` and it starts to work – coagmano Feb 24 '18 at 00:25
  • 1
    Now, there's the issue that `minimongo-standalone` has a totally different API to `minimongo`... the standalone version wraps up Meteor's implementation of minimongo and exposes not much other than `LocalCollection` – coagmano Feb 24 '18 at 00:32
  • 1
    Hey, @FredStark, your solution works (as you know). Feel free to edit your answer, or I may do it later on, so it provide a clean tutorials to willing learners. : ) – Hugo LOPEZ Feb 26 '18 at 10:58
  • 1
    Alright, I've edited it in. I feel like we've produced a great question/answer pair with and without bundling now haha – coagmano Feb 26 '18 at 22:17