I'm writing a meteor/angular2 app, and I have just upgraded to rc5. I get an error when I try to show a list of messages based on a mongo cursor in my component. I have tried to distill the code down, please let me know, if you need something more.
Here is the component:
import { Component, OnInit } from '#angular/core';
import { Mongo } from 'meteor/mongo';
import template from './messages-list.component.html';
#Component({
selector: 'messages-list',
template
})
export class MessagesListComponent implements OnInit {
messages: Mongo.Cursor<string>;
collection: Mongo.Collection<string>
ngOnInit() {
// just create an empty local collection for brevity, but it also fails with a named client/server collections
this.collection = new Mongo.Collection<string>(null);
this.messages = this.collection.find();
}
}
Here is the html template:
<ul>
<li *ngFor="let message of messages">
{{message}}
</li>
</ul>
This fails with a long stacktrace when I try to view the page, and several nested errors, but I think this seems to be the root of it:
Unhandled Promise rejection: (7)
"EXCEPTION: Error in ./MessagesListComponent class MessagesListComponent - inline template:0:10
ORIGINAL EXCEPTION: TypeError: undefined is not an object (evaluating 'async_1.ObservableWrapper.subscribe')
I can make the code work again by either changing the view or the component code as follows:
View:
<ul>
<!-- avoid iterating over messages -->
<!--li *ngFor="let message of messages">
{{message}}
</li-->
</ul>
Code:
// use a normal array instead of a cursor
export class MessagesListComponent implements OnInit {
messages: string[]
ngOnInit() {
this.messages = []
}
}
Here are the dependencies of my package.json:
"dependencies": {
"#angular/common": "2.0.0-rc.5",
"#angular/compiler": "2.0.0-rc.5",
"#angular/core": "2.0.0-rc.5",
"#angular/forms": "0.3.0",
"#angular/platform-browser": "2.0.0-rc.5",
"#angular/platform-browser-dynamic": "2.0.0-rc.5",
"#angular/router": "3.0.0-rc.1",
"angular2-meteor": "0.6.2",
"angular2-meteor-auto-bootstrap": "0.6.0",
"angular2-meteor-polyfills": "0.1.1",
"angular2-meteor-tests-polyfills": "0.0.2",
"es6-shim": "0.35.1",
"material-design-lite": "^1.2.0",
"meteor-node-stubs": "0.2.3",
"reflect-metadata": "0.1.3",
"rxjs": "5.0.0-beta.6",
"zone.js": "0.6.12"
}
Does anyone have an idea how to solve this?
I am facing quite the same issue, as you can see here.
First I had the error message "NgFor only supports binding to Iterables such as Arrays.", as I tried to iterate over a Mongo.Cursor.
The only idea I found was to fetch the cursor and to use an array instead. But the array did not contain any data, so I concluded that maybe there is no data available on client side and it's a Meteor issue. Maybe I am wrong and there is just an another way to transform the data from the cursor.
Today I also tried to solve this issue according to this file, but setting up this project failed.
Unfortunately, I did not find any useful and working examples according Angular 2 RC 5 and meteor mongo cursors, but I continue searching.
Related
I'm using ngx-material-timepicker in my project.when I use the latest 5.2.2, I'm getting the following error
ng:///NgxMaterialTimepickerModule/NgxMaterialTimepickerToggleComponent.n
gfactory.js:13 ERROR Error: No component factory found for NgxMaterialTimepickerContainerComponent. Did you add it to #NgModule.entryComponents?
at noComponentFactoryError (:4401/vendor.js:87649)
at CodegenComponentFactoryResolver.resolveComponentFactory (:4401/vendor.js:87714)
at DomService.appendTimepickerToBody (:4401/main-exams-exams-module.js:8424)
at NgxMaterialTimepickerComponent.open (:4401/main-exams-exams-module.js:8848)
at NgxMaterialTimepickerToggleComponent.open (:4401/main-exams-exams-module.js:8994)
at Object.eval [as handleEvent] (ng:///NgxMaterialTimepickerModule/NgxMaterialTimepickerToggleComponent.ngfactory.js:19)
at handleEvent (:4401/vendor.js:103240)
at callWithDebugContext (:4401/vendor.js:104859)
at Object.debugHandleEvent [as handleEvent] (:4401/vendor.js:104494)
at dispatchEvent (:4401/vendor.js:90327)
But when I downgraded to version 4.0.0 it worked perfectly.
// module page
import { NgModule } from '#angular/core';
import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker';
#NgModule({
declarations: [appComponent ],
imports: [NgxMaterialTimepickerModule]
]
})
html
<div>
<ngx-material-timepicker-toggle [for]="defaultValue"></ngx-material-timepicker-toggle>
<ngx-material-timepicker #defaultValue></ngx-material-timepicker>
<input aria-label="default time" [ngxTimepicker]="defaultValue" [value]="'05:11 pm'" required readonly>
</div>
Can someone help me with the latest version?
I was facing the same error and was able to fix it. Since you are using lazy load of angular you need to import NgxMaterialTimepickerModule in your app.module as well.
Im been trying the MongoDB Stitch service in Angular, so far Im able to use the service. However, the only way I could connect to the service is by including the js library hosted in AWS on the html page.
There is a mongodb-stitch npm package available and there are sample pages on mongodb tutorial on how to use it. But this is a pure JS library (no TS support) and I have tried several ways (using require, installing typings of the lib (not available), using #types) to no avail.
Anyone tried this on Ng4? Would love to have the steps you did to use the 'mongodb-stitch' package the create a service.
The other answer suggests instantiating a new instance of StitchClient which is something that MongoDB have explicitly advised against in the Official API Documentation - and with reason, since there is a factory method available for that purpose. So, (after installing mongodb-stitch), the following code would help you get started in component.ts
import { Component, OnInit } from "#angular/core";
import { StitchClientFactory } from "mongodb-stitch";
let appId = 'authapp-****';
#Component({
selector: "app-mongo-auth",
templateUrl: "./mongo-auth.component.html",
styleUrls: ["./mongo-auth.component.css"]
})
export class MongoAuthComponent implements OnInit {
mClient;
ngOnInit() {
this.mClient = StitchClientFactory.create(appId);
}
And you can then use this for whatever purpose you want, such as for implementing sign-in with Google
gLogin(){
this.mClient.then(stitchClient => {
stitchClient.authenticate("google");
})
not sure whether the question is still relevant considering it was asked two months ago but anyway...
As you pointed out you can use
npm install --save mongodb-stitch
to install the package and since there is no TS binding you can declare the stitch library as any
For example:
declare var stitch: any;
export class MyService implements OnInit {
db;
client;
ngOnInit() {
this.client = new stitch.StitchClient('<check the stitch app page for proper value>');
this.db = this.client.service('mongodb', 'mongodb-atlas').db('<the db name goes here>');
this.client.login();
}
save() {
this.db.collection('<collection name>').insertOne({key : 'value'}).then(() => console.log("All done"));
}
}
the previous answers are functional, but i wanna share a example using a service injectable.
service.ts
import { Injectable } from '#angular/core';
import { Jsonp, URLSearchParams } from '#angular/http';
import { StitchClientFactory } from "mongodb-stitch";
import 'rxjs/add/operator/map';
#Injectable()
export class Service {
constructor(private jsonp: Jsonp) { }
client;
connect(){
this.client = new StitchClientFactory.create("App ID"); // Slitch apps > Clients > App ID
this.client.then(stitchClient => stitchClient.login())
.then((stitchClient) => console.log('logged in as: ' + stitchClient))
.catch(e => console.log('error: ', e));
}
all() {
this.connect();
return this.client.then(stitchClient => {
let db = stitchClient.service('mongodb', 'mongodb-atlas').db("database Name"); // Slitch apps > mongodb-atlas > Name database.Collection
let itemsCollection = db.collection('name collection'); // Slitch apps > mongodb-atlas > Name database.Collection
console.log(itemsCollection.find().execute());
return itemsCollection.find().execute();
})
.then(result => {return result})
.catch(e => console.log('error: ', e));
}
}
after make the previous file, you must create a module to receive the data, so:
module.ts
import { Component, OnInit, Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { StitchClientFactory } from "mongodb-stitch";
import { Service } from 'service'; // previous code
declare var stitch: any;
#Component({
template: '
<ul class="demo-list-icon mdl-list">
<li class="mdl-list__item" *ngFor="let item of data | async">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon">{{propiedad.nombre}}</i>
</span>
</li>
</ul>
'
})
export class MainComponent implements OnInit {
data: Observable<[]>;
constructor(private Service: service) {
}
ngOnInit() {
this.propiedades = this.Service.all();
}
}
important, you don´t must forget to add service on module.ts intitial declarations.
mongodb Atlas
mongodb-stitch vía NPM
Documentation mongoDB Stitch.
Sure!
Windows 7 x64
aurelia-cli 0.23.0
syncfusion 14.4.20
jquery 3.1.1
I saw the other question regarding this but it doesn't seem to follow the bootstrap example. I believe Syncfusion should also be setup using the bootstrap example as a template but I cannot seem to get it to work.
My test project is just a new aurelia-cli project with default settings.
I am using the ejDatePicker control as an example.
aurelia.json I added
{
"name": "jsrender",
"path": "../node_modules/jsrender",
"main": "jsrender",
"deps": ["jquery"],
"exports": "$"
},
{
"name": "syncfusion",
"path": "../node_modules/syncfusion-javascript",
"main": "/Scripts/ej/web/ej.web.all.min",
"deps": ["jquery", "jsrender"],
"exports": "$",
"resources": [
"Content/ej/web/ej.widgets.core.min.css",
"Content/ej/web/bootstrap-theme/ej.theme.min.css"
]
}
app.html
<template>
<require from="syncfusion/Content/ej/web/ej.widgets.core.min.css"></require>
<require from="syncfusion/Content/ej/web/bootstrap-theme/ej.theme.min.css"></require>
<!--Container for ejDatePicker widget-->
<input id="startDate" type="text" />
</template>
app.js
export class App {
constructor(){
$("#startDate").ejDatePicker();
}
}
main.js
import 'jquery';
import 'jsrender'
import 'syncfusion'
......
I am not getting any errors but the control is not displaying. However if I remove the suncfusion config from aurelia.json then $("#startDate").ejDatePicker(); complains that ejDatePicker is not valid so to me that means that the config in aurelia.json is pulling in the correct javascript file.
I had the $("#startDate").ejDatePicker(); in the constructor instead of attached(). It is working after I made that change.
A Meteor/React noob here, going through the Meteor-React tutorial and got stuck on step 3. My problem is that the data is not being displayed in the browser, although it exists in the db.
Here is my imports/ui/App.jsx:
import React, { Component, PropTypes } from 'react';
import { createContainer } from 'meteor/react-meteor-data';
import { Tasks } from '../api/tasks.js';
import Task from './Task.jsx';
class App extends Component {
renderTasks() {
return this.props.tasks.map((task) => (
<Task key={task._id} task={task} />
));
}
render() {
return (
<div className="container">
<header>
<h1>Todo List</h1>
</header>
<ul>
{this.renderTasks()}
</ul>
</div>
);
}
}
App.propTypes = {
tasks: PropTypes.array.isRequired,
};
export default createContainer(() => {
return {
tasks: Tasks.find({}).fetch(),
};
}, App);
No errors show up in console.
Basically this.props.tasks returns empty array. But db.tasks.find({}) in console shows records. Without changing much around, if I hardcode Tasks records, they display alright, so the issue isn't with Task component. Anyone can help here? Would much appreciate.
client/main.jsx:
import React from 'react';
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import App from '../imports/ui/App.jsx';
Meteor.startup(() => {
render(<App />, document.getElementById('render-target'));
});
package.json:
{
"name": "simple-todos",
"private": true,
"scripts": {
"start": "meteor run"
},
"dependencies": {
"meteor-node-stubs": "~0.2.0",
"react": "^15.1.0",
"react-addons-pure-render-mixin": "^15.1.0",
"react-dom": "^15.1.0"
}
}
npm version 3.3.12
node version 5.6.0
As of your description from, it seems that your database is not accessible on both server & client. May be you forgot to add the reference of your database in the server side. try to import your tasks main.js file of your server.
Make sure your server/main.js has the following line:
import '../imports/api/tasks.js';
Dummy question ...
I try to code an angular2 (2.0.0-beta.6) app in Typescript in jsfiddle.
I know that there is other solution online but ...
In fact, my example is very small and the problem is on import module :
import {bootstrap} from 'angular2/platform/browser'
import {Component} from 'angular2/core';
I got the following error :
Uncaught ReferenceError: System is not defined
Uncaught ReferenceError: require is not defined
I try to add some dependencies (require, system ...) but it doesn't work.
And there is no more Self-Executing bundle for recent version (beta-6) of Angular2 (angular2.sfx.dev.js).
Some tests :
https://jsfiddle.net/asicfr/q8bwosfn/1/
https://jsfiddle.net/asicfr/q8bwosfn/3/
https://jsfiddle.net/asicfr/q8bwosfn/4/
https://jsfiddle.net/asicfr/q8bwosfn/5/
https://jsfiddle.net/asicfr/q8bwosfn/6/
In Plunker you can just use the menu
New > Angularjs > 2.0.x (TS)
to get a minimal working Angular2 application
Router
If you want to use the router add in config.js
'#angular/router': {
main: 'router.umd.js',
defaultExtension: 'js'
},
<base href="."> as first child in the <head> of index.html might be necessary as well.
To switch to HashLocationStrategy change main.ts from
import {bootstrap} from '#angular/platform-browser-dynamic';
import {App} from './app';
bootstrap(App, [])
.catch(err => console.error(err));
to
import {bootstrap} from '#angular/platform-browser-dynamic';
import {App} from './app';
import {provide} from '#angular/core'
import {ROUTER_PROVIDERS} from '#angular/router';
import {LocationStrategy, HashLocationStrategy} from '#angular/common';
bootstrap(App, [ROUTER_PROVIDERS, provide(LocationStrategy, {useClass: HasLocationStrategy}])
.catch(err => console.error(err));
If you are not tied to JS Fiddle, consider Plunker instead. The Angular devs keep a bare workspace up to date with new Angular releases at this link.
It is more current than even Plunker's own Angular 2 setup (which you can access from the Plunker menu: New > AngularJS > 2.0.x (TS)
The downside: that setup is in TypeScript, so if you wish to develop with vanilla Javascript (ES5 or ES6), your best bet is to use the Plunker menu option instead.
You need also to include SystemJS JS file. I saw that you missed it. All these includes are necessary:
<script src="https://code.angularjs.org/2.0.0-beta.3/angular2-polyfills.js"></script>
<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.3/Rx.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.3/angular2.dev.js"></script>
You also need then to configure SystemJS with the following code and then import your main module containing the bootstrap function:
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true },
packages: {
'app': {
defaultExtension: 'ts'
}
}
});
System.import('app/main')
.then(null, console.error.bind(console));