Collection.insert is not a function - Meteor - meteor

Good day developers! I'm working with Meteor.js it's my 1st expirience
I created collection in file
// ./dbs/messages.js
import { Mongo } from 'meteor/mongo';
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
export const Messages = new Mongo.Collection('messages');
and use it in api point with calling Messages.insert like that
// server/mail.js
import Messages from './dbs/messages.js';
Meteor.methods({
'message.post'(messageText, location){
Messages.insert({
messageText: messageText,
location: location
});
}
})
But when I call 'message.post' I get an error
Exception while invoking method 'message.post' TypeError
Messages.insert is not a function
BUT, when I comment collection import and declare it in server/main.js like that
// import Messages from './dbs/messages.js';
const Messages = new Mongo.Collection('messages');
Meteor.methods({
'message.post'(messageText, location){
Messages.insert({
messageText: messageText,
location: location
});
}
});
In this case my Messages.insert works properly.
Who has experience with Meteor - can you explain me what is the reason?
Thanks!
Also I have removed autopublish and insecure packages

As #MasterAM and #Ankur Soni said you need to import Messages using brackets import { Messages } from './dbs/messages.js';
The only way to import without brackets is by defining Messages and then exporting it like so export default Messages;

I initiate my collections in a "common" space. I feel what you did is actually right. You either declare the collection twice, once on the client side and once on the server side or do it only once in a common folder. I see in many documentations that the popular place to keep these declarations is the /imports/api ... which is common to both server and client.
Rgs,
Paul

Related

Redux Persist + Redux toolkit $CombinedState error

I'm trying to add redux persist to redux toolkit but for some reason I get an Exported variable 'store' has or is using name '$CombinedState' from external module ".../node_modules/redux/index" but cannot be named. error on vscode.
This is my store configuration file with the added persist config, which if I remove, works fine.
import { configureStore } from "#reduxjs/toolkit";
import { persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import { createEpicMiddleware } from "redux-observable";
import rootEpic from "onsite/redux/rootEpic";
import rootReducer from "onsite/redux/rootReducer";
const epicMiddleware = createEpicMiddleware();
const persistConfig = {
key: "root",
storage: storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
// Line that shows error
const store = configureStore({
reducer: persistedReducer,
middleware: [epicMiddleware],
});
export default store;
epicMiddleware.run(rootEpic);
Other things I have tried are putting the combineReducers declaration (from rootReducerimport) into the same file or converting the file into plain javascript, with same or similar results. For some reason typescript decides to still haunt me on a javascript file :)
The code still runs, so I'm tempted to leave it like that, but I would like to get rid of it.
I had the same issue, and here's what I figured out:
You need to include Store from redux, and use it as your type definition for your own store return value. Short answer:
import { Store } from 'redux';
[...]
const store:Store = configureStore([...])
[...]
export default store;
Longer answer:
As I understand it, what was happening is that Store type uses $CombinedState as part of its definition. When configureStore() returns, it inherits the State type. However since State is not explicitly used in your code, that now means that your code includes a value that references $CombinedState, despite it not existing anywhere in your code either. When you then try to export it out of your module, you're exporting a value with a type that doesn't exist within your module, and so you get an error.
You can import State from redux (which will in turn explicity cause your code to bring in $CombinedState), then use it to explicitly define store that gets assigned the return of configureStore(). You should then no longer be exporting unknown named types.
You can also be more specific with your Store type, as it is a generic:
const store:Store<RootState>
Although I'm not entirely sure if that would be a circular dependency, since your RootState depends on store.
Adding a
import { $CombinedState } from '#reduxjs/toolkit'
in that file should usually resolve that error.

Meteor query runs perfectly fine on server but not on client

So I have a simple server file:
import { Meteor } from 'meteor/meteor';
const Animals = new Mongo.Collection("animals");
let animalsFindOne = Targets.findOne({animal: "henry"});
console.log(_.get(animalsFindOne, 'food.favorite.amount'));
And a animals.js file that renders to the template
import {Template} from "meteor/templating";
import {Mongo} from "meteor/mongo";
import "/imports/ui/targets/animals.html";
const Animals = new Mongo.Collection("animals");
let animalsFindOne = Targets.findOne({animal: "henry"});
Template.targets.helpers({
foodAmount: function() {
return _.get(animalsFindOne, 'food.favorite.amount';
}
});
I could return "foo" as foodAmount and the template would render it perfectly fine. For _.get I use erasaur:meteor-lodash, which works perfectly fine in server.js. In the server console the output is "5", the output that is expected and great.
What piece am I missing here?
Edit: Also I have autopublish installed, and I am not looking forward to removing it, as this software is a test anyways.
The animalsFindOne is already defined outside the foodAmount helper, thus it won't trigger the Template's reactivity-based redrawing mechanism.
In order to gain reactivity in helpers you need to call queries within the helper:
import {Template} from "meteor/templating";
import {Mongo} from "meteor/mongo";
import "/imports/ui/targets/animals.html";
const Animals = new Mongo.Collection("animals");
Template.targets.helpers({
foodAmount: function() {
let animalsFindOne = Targets.findOne({animal: "henry"});
return _.get(animalsFindOne, 'food.favorite.amount';
}
});
edit: Meteor allows optional chaining with the more recent versions, so no need for lodash here:
Template.targets.helpers({
foodAmount: function() {
let animalsFindOne = Targets.findOne({animal: "henry"});
return animalsFindOne?.food?.favorite?.amount
}
});

How do I correctly import my collection definition?

How do I correctly import my collection definition?
I get this error message when as a result of trying to import
I externalized my collection definition FROM the main myMeteorApp.js file:
(My directory structure looked like this:)
/myMeteorApp
/myMeteorApp.js
...TO the tasks.js file:
(My directory structure currently looks like this:)
/myMeteorApp
--/imports/api/tasks.js
The contents of tasks.js look like this:
import { Mongo } from "meteor/mongo";
const Images = new FS.Collection("images", {
stores: [new FS.Store.FileSystem("images", {path: "~/uploads"})]
});
const buyList = new Mongo.Collection("BuyList");
const WhoAreWe = new Mongo.Collection("whoDb");
const merchantReviews = new Mongo.Collection("MerchantReviews");
const Messages = new Meteor.Collection("messages", {transform: function (doc) { doc.buyListObj = buyList.find({sessionIDz: {$in: [doc.buyList]}}); return doc; }});
export { Images };
export { buyList };
export { WhoAreWe };
export { merchantReviews };
export { Messages };
I have packages babel-preset-es2015 and ecmascript installed, but these haven't helped.
Looking forward to your help...
Everything is the chat session we had indicates that your original app used Meteor 1.2, which did not support ES2015 modules. In addition, you did not import them correctly.
Here is a short checklist for import-related issues:
Make sure that your project is actually using Meteor v1.3+ (run meteor --version). Earlier versions did not support the modules feature.
Make sure that you have the ecmascript package installed (run meteor list or cat .meteor/packages | grep ecmascript from your project's root directory. If not, meteor add ecmascript. This is the package used for compiling ES2015.
Make sure that you are using it correctly. There are 2 types of exports:
default - import foo from 'imports/bar' goes with export default bar.
named - import { foo } from 'imports/bar' goes with export const foo = ..., etc.

Import file structure and collection publish

Following Meteor docs on how to use the import directory structure, Example directory layout.
//-------------- publication.js`
import {Vehicles} from '../vehicles.js';
Meteor.publish('vehicles', function () {
return Vehicles.find();
});
//-------------- carClass.jsx
import './vehicles/server/publications.js';
const composer = (props, onData) => {
const subscription = Meteor.subscribe('vehicles');
if (subscription.ready()) {
const vehicle = Vehicles.findOne({name: 'jack'});
onData(null, { vehicle });
}
};
Does the publish method need to be exported?
Error in browser console saying:
Uncaught Error: Cannot find module './vehicles/server/publications.js'
How can this error be fixed? Thanks
Meteor publications are server-only code, so you can't import that script in carClass.jsx.
You should have some file like {app root}/server/main.js. You import your publications here to make them available for client scripts to subscribe to. It's important that this file isn't inside of the /imports folder, so that it is eagerly loaded when the server starts.
The problem is that the path ./vehicles/server/publications.js is not reachable from the carClass.jsx file. You should reference it by ./server/publications.js

How to get access to native Firebase object when using angularfire2?

I'm using AngularFire2 (2.0.0-beta.2) incombination with angular2 (2.0.0-rc.4). I'd like to get access to the native firebase object (not the AngularFire root object) from Angularfire2.
Within my component, I want to make calls like:
firebase.auth().currentUser.updateEmail("user#example.com")
where firebase is the native firebase object, like that you get from the fragment below:
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase.js"></script>
<script>
// Initialize Firebase
// TODO: Replace with your project's customized code snippet
var config = {
apiKey: "apiKey",
authDomain: "projectId.firebaseapp.com",
databaseURL: "https://databaseName.firebaseio.com",
storageBucket: "bucket.appspot.com",
};
firebase.initializeApp(config);
</script>
But I don't understand how to setup my angular2 component so that the firebase object is visible within it. Probably a very simple problem to solve, but I don't know how to solve -- I'm not an angular2 expert. I was hoping there would be and AngularFire api to get the object, but there is not.
Also, the reason that I'm trying to do this is that I don't think the angularfire2 api's are complete yet (thats understandable as its still in beta) and I'm trying to work around this. For example I want to update the users email address or password, or send them the forgotten password email. None of this functionality seems to exist yet in AngularFire2, so I'm trying to implement using the native Firebase object.
If you're reading this in September 2016 onwards, this approach might sound good to you.
See the code for superior understanding:
import { Component, Inject } from '#angular/core';
import { AngularFire, FirebaseApp } from 'angularfire2';
#Component({
templateUrl: 'app/auth/resetpassword.component.html'
})
export class ResetpassComponent {
public auth: any;
constructor(private af: AngularFire, #Inject(FirebaseApp) firebaseApp: any) {
this.auth = firebaseApp.auth()
console.log(this.auth);
}
// formData.value.email = 'your#email.com';
onSubmit(formData) {
if(formData.valid) {
console.log('Sending email verification');
this.auth.sendPasswordResetEmail(formData.value.email)
.then( (response) => {
console.log('Sent successfully');
})
.catch( (error) => {
console.log(error);
})
}
}
}
In English:
Import Inject and FirebaseApp
Make available in your component
Start using all the native javascript SDK functions and methods, such as sendPasswordResetEmail()
Doing a auth. doesn't autocomplete with the available methods and functions, so you might need the docs close to you, such as this: https://firebase.google.com/docs/auth/web/manage-users
Any thanks? Give to #cartant : https://stackoverflow.com/a/39069813/1757321
I'm going to try and answer my own question. Let me first say that I'm sure my answer is not the most elegant solution, I'm not yet a javascript/typescript/angular expert. But my answer does work -- even if I don't completely understand.
I used angular-cli to setup my project which is based on angular2 and the latest firebase. Apparently when you use this to setup your project there is a global object created with the name "firebase" in existence. One way to make it visible within your angular 2 component is to put this declaration at the global level in you component (right after the import statements and before your class declaration).
declare var firebase : any;
After you do this the global firebase object is available for use in your component.
RanchoSoftware's solution did not work for me, i used
import {AngularFireModule} from "angularfire2";
import *as firebase from 'firebase';
within the imports in the app.module.ts file
found here:
https://github.com/angular/angularfire2/issues/445

Resources