ReactJS, MeteorJS, and MongoDB: Getting collection from different collection value? - mongodb

Okay, so, I have a component with a function getPhotos(), which is taking in a string from parent props:
import React, { Component, PropTypes } from 'react';
// data
import { Cats } from '../api/collections/galleries.js';
export default class...
getPhotos() {
let gallery = this.props.galleryName; // gallery = "Cats"
Now, I want to use this string "Cats" to access a collection from mongo db, so I tried using window["Cats"], but I don't think it is on the window object:
let photoData = window[gallery].find().fetch(); // window[Cats] and window["Cats"] returns undefined
return photoData;
}
Everything in meteor seems to be working, publish and subscribe.
Any ideas how I can do this using React components?

You can do
Meteor.connection._stores[gallery]._getCollection().find().fetch();

Related

Vuex ORM model constructor issue on insert

I have the following model:
import { Model } from '#vuex-orm/core'
export class User extends Model {
static entity = 'users'
static fields () {
return {
id: this.attr(null),
name: this.attr('')
}
}
}
and when I try to do this:
User.insert({
data: { id: 1, name: 'John' }
})
I get the following error:
Uncaught (in promise) TypeError: Class constructor User cannot be invoked without 'new'
Any idea what is the problem? This code is from the documentation, so I'm confused a little bit.
as I can see you are missing the registration of the model in the database at the beginning of the application.
You have to implement your vuex store with the corresponding plugin
EXAMPLE:
import Vue from 'vue'
import Vuex from 'vuex'
import VuexORM from '#vuex-orm/core'
import User from '#/models/User'
import Post from '#/models/Post'
Vue.use(Vuex)
// Create a new instance of Database.
const database = new VuexORM.Database()
// Register Models to Database.
database.register(User)
database.register(Post)
// Create Vuex Store and register database through Vuex ORM.
const store = new Vuex.Store({
plugins: [VuexORM.install(database)]
})
export default store
You now have good documentation in this regard
I hope I have helped you, greetings

"TypeError: this.types is not a function" when using "vuex-orm-decorators"

I'm trying to use the npm package 'vuex-orm-decorators' from https://github.com/scotley/vuex-orm-decorators#readme
When I try to insert into the DB, I get the error TypeError: this.types is not a function
Entity looks like this
import { Model } from "#vuex-orm/core";
import { NumberField, OrmModel, StringField } from "vuex-orm-decorators";
#OrmModel("races")
export default class Race extends Model {
#NumberField()
public ID!: number;
#StringField()
public Name!: string;
}
store looks like this:
import Vue from "vue";
import Vuex from "vuex";
import { ORMDatabase } from "vuex-orm-decorators";
Vue.use(Vuex);
export default new Vuex.Store({
.
.
.
plugins: [ORMDatabase.install()]
});
Also, maybe this is a clue.... in Vuex-Orm, this.setters is returning a value, but this.setters('all') is returning undefined.
/**
* Get all records.
*/
Model.all = function () {
return this.getters('all')();
};
From seeing the undefined basic fields and functions, it seems like the vuex-orm database isn't getting set up correctly. Any ideas?
I tried to create a stackoverflow tag for vuex-orm-decorators, but I'm not quite at 1500 rep yet, so I just tagged it as vuex-orm.
There is a small bug in vuex-orm-decorators package in the implementation of the types function defined in Vuex-ORM Single Table Inheritance docs.
I've created a fork in which I fixed this simple problem and created a pull request to update the original package.
Lastly, I've to point that from my tiny dive into this package that it isn't fully ready yet for table inheritance features built in Vuex-ORM but still is great for simple use cases.

Ionic 4 Angular 7 - passing object/data to another page [duplicate]

This question already has answers here:
Ionic 4. Alternative to NavParams
(8 answers)
Closed 4 years ago.
I would like to pass a JSON object to another page. What I've tried is to pass the JSON string using Angular router ActivatedRoute like this:
this.router.navigate(['details', details]);
and then retrieve it like this:
import { ActivatedRoute } from '#angular/router';
constructor(private activatedRoute: ActivatedRoute) {
}
ngOnInit() {
this.activatedRoute.params.subscribe(extras => {
console.log(extras);
this.JSONObject = extras;
});
}
It is possible to do it this way but what happened was the nested JSON objects becomes inaccessible. It turns into this string:
"[object Object]"
The stringified JSON object is fine and accessible before I pass it. Another problem is that it appends the JSON string to the url so it doesn't look that nice. From what I read as well, it is not a good practice to pass something more than just an id this way.
I am thinking of something like passing objects as intent extras between activities in Android. I've searched the documentations, forums, and previous stackoverflow questions but I didn't found any solution that enables me to achieve this. Is there any other way of passing objects between pages using Angular router in Ionic4?
I solved it using a service with a simple setter and getter just like in this question that I later found:
Ionic 4. Alternative to NavParams
First, I create a service with setter & getter:
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class NavExtrasService {
extras: any;
constructor() { }
public setExtras(data){
this.extras = data;
}
public getExtras(){
return this.extras;
}
}
Let's say I'm navigating from page A to page B, in page A:
this.navExtras.setExtras(extras)
this.router.navigateByUrl('page-b');
Then in Page B, I retrieve the extras this way:
this.location = navExtras.getExtras();
It works so far although I'm still not sure if there are better ways to do it..

Meteor: Minimongo does not synchronize with MongoDB

My Meteor application using Angular 2 and Typescript seems not to load the server data on the client side: I have followed this tutorial, both with autopublish turned on and of, but each time several tries to display data on client side with different collections failed.
Unlike in the tutorial (RC4), I am using Angular 2 RC5. My clients' main.ts looks as following:
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app.module';
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
Now I tried to copy the very simple sample from the tutorial using the collection "parties" (autopublish turned on).
I created the file both/collections/parties.collection.ts:
import {Mongo} from 'meteor/mongo';
import {Party} from '../interfaces/party.interface';
export const Parties = new Mongo.Collection<Party>('parties');
Instead of using the app.component.ts, I bind the collection in an another existing and functional component which looks like following:
import { Component } from '#angular/core';
import { Mongo } from 'meteor/mongo';
import template from './my-component.component.html';
import { Parties } from '../../../both/collections/parties.collection';
import { Party } from '../../../both/interfaces/party.interface';
#Component({
selector: 'my-selector',
template
})
export class MyComponent
{
parties: Mongo.Cursor<Party>;
constructor() {
this.parties = Parties.find();
alert(this.parties.count());
}
}
If I call db.parties.find({}); in the mongo console, it returns three rows, because I have set up the server side inserts from the sample.
My html template is the same as in the tutorial:
<ul>
<li *ngFor="let party of parties">
<a [routerLink]="['/party', party._id]">{{party.name}}</a>
<p>{{party.description}}</p>
<p>{{party.location}}</p>
<button (click)="removeParty(party)">X</button>
</li>
alert(this.parties.count()) returns "0" - both trying Mongo.Cursor and Mongo.Cursor. I have also tried to fetch the cursor and to alert the array. Each time I get "0" and the error message "NgFor only supports binding to Iterables such as Arrays.", but I think it fails because the client does not get the data the server has.
This is no more an issue on recent versions of angular2.0-meteor.

meteor-reactjs: in constructor collection is empty

Due to the fact that I am new in meteor/react I can't figure out how to initialize my state variable.
My problem is that I would like to get
my mongo collection through the createContainer from react-meteor-data (as described here),
use the initialized prop to intialize the state variable
But the prop in the constructor is empty. Only when I the "gotClicked" function is called the prop.allLists is filled with the data from mongo.
Does anyone know why? My guess the data is loaded asynchronously, so that the data is not available yet in the constructor.
What would be a better way to get the data?
import React, {Component, PropTypes} from 'react';
import { createContainer } from 'meteor/react-meteor-data';
import {AllLists} from '../api/alllists.js'
export default class MyList extends Component {
constructor(props) {
super();
console.log(props.allLists)
console.log(this.props.allLists)
//allLists is empty
this.state = {
lists: props.allLists
}
}
gotClicked(){
console.log(this.props.allLists)
//allLists is filled
}
render() {
return (
<div className="container" onClick={this.gotClicked.bind(this)}>
</div>
);
}
}
MyList.propTypes = {
allLists: PropTypes.string.isRequired
}
export default createContainer(() => {
return {
allLists: AllLists.find({}).fetch()
};
}, MyList);
You're right, the data is loaded asynchronously, and it might not be available in the constructor. However, the callback function you pass to createContainer is evaluated again when the data is loaded, and it automatically updates the props of your component.
To catch this change, implement the componentWillReceiveProps function in your React component.
componentWillReceiveProps(nextProps) {
this.setState({
lists: nextProps.allLists
});
}
Docs here: https://facebook.github.io/react/docs/component-specs.html