Problems in lesson from angular-meteor.com - mongodb

I start to learn angular2 and meteor, from http://angular-meteor.com/tutorials/angular2/3-way-data-binding
And in 3th lesson i have 2 error in console:
refreshingclient/app.ts (18, 11): Generic type 'Array<T>' requires 1 type argument(s).
client/app.ts (20, 19): Cannot find name 'zone'.
when i added some documents to Mongo from command line, they not appear on page.
and my app.ts file:
/// <reference path="../typings/angular2-meteor.d.ts" />
import {Component, View, NgFor} from 'angular2/angular2';
import {Parties} from 'collections/parties';
import {bootstrap} from 'angular2-meteor';
#Component({
selector: 'app'
})
#View({
templateUrl: 'client/app.html',
directives: [NgFor]
})
class Socially {
parties: Array;
constructor() {
Tracker.autorun(zone.bind(() => {
this.parties = Parties.find().fetch();
}));
}
}
bootstrap(Socially);
what is the problem?

In the client/app.ts file, the instructions (http://angular-meteor.com/tutorials/angular2/3-way-data-binding) show:
class Socially {
parties: Mongo.Cursor;
constructor () {
this.parties = Parties.find();
}
}
It should actually be:
class Socially {
parties: Mongo.Cursor<Object>;
constructor () {
this.parties = Parties.find();
}
}
Notice <Object> has been added after Mongo.Cursor.
If you go to Step 4, there is a link to download a zip file of the code (https://github.com/Urigo/meteor-angular2.0-socially/archive/step_03.zip). You'll see in there that the code is correct.

kuka-
main.ts and load_parties.ts are there just to create data in your db if there is none. So if adding those files made it work, there must have been something wrong with the data you created from the command line. My guess is the data you added from the command line went to the wrong collection (i.e. Party vs party). You can check your collections and data by typing
meteor mongo
at the root of your project to get a mongo prompt. Then at the mongo prompt type
show collections
This will display all collections in your db. You should have one called 'parties'. Type the following to see the content.
db.parties.find().pretty()
Study the data to make sure all property names are identical. If you created a property call 'partyName' and your form is looking for 'name', nothing will show up.

Related

How do I add a new JS function via mixin to the Magento checkout payment page's shipping information section?

I am trying to add a mixin in Magento 2 for the checkout/payment page shipping info section.
There is an existing section in vendor/magento/module-checkout/view/frontend/web/template/shipping-information/address-renderer/default.html as follows:
<each args="data: address().customAttributes, as: 'element'">
<text args="$parent.getCustomAttributeLabel(element)"/>
<br/>
</each>
I want to create a myNewFunction() and call it from here. So, I have temporarily added if="$parent.myNewFunction(element)" to it, like this:
<each args="data: address().customAttributes, as: 'element'">
<text if="$parent.myNewFunction(element)" args="$parent.getCustomAttributeLabel(element)"/>
<br/>
</each>
That pre-existing function getCustomAttributeLabel is defined in vendor/magento/module-checkout/view/frontend/web/js/view/shipping-information/address-renderer/default.js.
This is where I need to add my myNewFunction() at. I don't want to override that entire file and duplicate it into my theme, so I am trying to add the function to it via mixin.
To do this, I have stubbed out a module: app/code/MyCompany.
In this module, I have created:
app/code/MyCompany/Checkout/view/frontend/requirejs-config.js
with this code:
var config = {
config: {
mixins: {
'Magento_Checkout/js/view/shipping-information/address-renderer/default': {
'MyCompany_Checkout/js/view/shipping-information/address-renderer/default-mixin': true
}
}
}
};
Then I created the mixin itself in:
app/code/MyCompany/Checkout/view/frontend/web/js/view/shipping-information/address-renderer/default-mixin.js
with this code:
define([
'uiComponent',
'underscore',
'Magento_Customer/js/customer-data'
], function (Component, _, customerData) {
'use strict';
return function (target) {
return target.extend({
myNewFunction: function (element) {
console.log(element);
return false;
}
});
}
});
I currently have deploy mode set to "development" in Magento. Nonetheless, I have tried removing all the var/* files, generating static content again, and clearing the cache, for good measure.
No matter what, upon loading the checkout/payment page, I keep getting this JS error in the console:
$parent.myNewFunction is not a function
What am I doing wrong here?
I suspected the module needs to have a register.php? Or the module is not loading? Yet, I have seen plenty of other examples such as this guide, this Magento mixin stackoverflow question, and this example on how to add shipping.js functionality via mixin, none of which mention doing anything more with the module other than declaring the requirejs-config.js and the mixin JS file itself.
Just found a way to override that function using 'mixins'.
On requirejs-config.js file I had to add:
config: {
mixins: {
'Magento_Checkout/js/view/shipping': {
'Mynamespace_Mymodule/js/view/shipping': true
}
}
}

nextjs import but don't invoke function throws Module not found: Error: Can't resolve 'dns'

My project(NextJS) was working fine and suddenly I am experiencing the issue ModuleNotFoundError. Particularly in the case of dynamic routing of nextJs.
Error I see is: Module not found: Error: Can't resolve 'dns'
In the pages directory pages/programs/[programtype]/[program].jsx when mongo is imported, it throws:
ModuleNotFoundError: Module not found: Error: Can't resolve 'dns' in 'node_modules/mongodb/lib'
Full error dump:
ModuleNotFoundError: Module not found: Error: Can't resolve 'dns' in '/project-path/node_modules/mongodb/lib'
at /project-path/node_modules/webpack/lib/Compilation.js:925:10
at /project-path/node_modules/webpack/lib/NormalModuleFactory.js:401:22
at /project-path/node_modules/webpack/lib/NormalModuleFactory.js:130:21
at /project-path/node_modules/webpack/lib/NormalModuleFactory.js:224:22
at /project-path/node_modules/neo-async/async.js:2830:7
at /project-path/node_modules/neo-async/async.js:6877:13
at /project-path/node_modules/webpack/lib/NormalModuleFactory.js:214:25
at /project-path/node_modules/enhanced-resolve/lib/Resolver.js:213:14
at /project-path/node_modules/enhanced-resolve/lib/Resolver.js:285:5
at eval (eval at create (/project-path/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:13:1)
at /project-path/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js:44:7
at /project-path/node_modules/enhanced-resolve/lib/Resolver.js:285:5
at eval (eval at create (/project-path/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:13:1)
at /project-path/node_modules/enhanced-resolve/lib/Resolver.js:285:5
at eval (eval at create (/project-path/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:25:1)
at /project-path/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:67:43
The problem
This is a subtle problem with server-side code in Next.js.
The error is clear - you're trying to execute server side code (mongo query) in a client side code. But the cause is not obvious, because with Next.js you should be able to call Mongo from your components.
The cause
Next.js throws this error because you are importing your mongo code without using it.
It sounds weird but it is true.
How to avoid it
To avoid this error just remove any server-side code import in your components if you don't use it in getServerSideProps.
It sounds even more weird but it is true.
Good and bad examples
This works fine:
import { findUsers } from '../lib/queries'
function Home({ users }) {
return (
<h1>Users list</h1>
//users.map and so on...
)
}
export async function getServerSideProps() {
const users = await findUsers()
return {
props: {
users: users
}
}
}
export default Home
While this will throw the error:
import { findUsers } from '../lib/queries'
function Home({ users }) {
return (
<h1>Users list</h1>
//users.map and so on...
)
}
export async function getServerSideProps() {
// call disabled to show the error
// const users = await findUsers()
return {
props: {
users: [] //returning an empty array to avoid other errors
}
}
}
export default Home
Keep your server-side coding modules (for e.g: models, database connection maker) outside of the Page directory.
For reference: https://nextjs.org/docs/messages/prerender-error
If you're getting this error with Next-js auth, make sure your "lib" folder is in the root directory.
Here's the structure
my problem was that i used a function in initialprops wich was exported via module.exports instead of export default
I created a directory called 'api-lib' in my project root directory to add my queries and that caused this error to appear.
And I solved it by moving my 'api-lib' directory into the main 'src' directory.
My issue was exporting getServerSideProps with all of it's server side operations from a component, where it should only be placed and exported from a PAGE component.
Moving getServerSideProps to the main page component and just drilling down what I needed to the child component solved it for me.

Vue2 - Importing Classes, Access and Instantiation

By importing classes at two places do I create 2 different instances?
* content of "MyClass.js"
class MyClass {
constructor() {}
isAuthenticated() {}
}
const cls = new MyClass();
export default cls;
--------------------------------
* content of "router.js"
import auth from "./MyClass";
Vue.use(Router)
--------------------------------
content of "./plugins/MyPlugin.js"
import clsInstance from "./MyClass";
export default {
install(Vue) {
Vue.prototype.$auth = clsInstance;
}
}
--------------------------------
* content of main.js
import myFirstPlugin from "./plugins/MyPlugin.js";
Vue.use(myFirstPlugin);
router.beforeEach((to, from, next) => {
if( auth.isAuthenticated() ){}
}
new Vue({
router
})
--------------------------------
* content of someComponent.vue
methods: {
logOut() {
this.$auth.isAuthenticated()
}
}
Is "auth.isAuthenticated" inside of "router.beforeEach" in "main.js"
identical
with
this.$auth.isAuthenticated() inside of "logOut" in "someComponent.vue"
or there are actually two different instances of "MyClass"created?
import is much the same as require. The code in MyClass.js will only be run once, creating a single instance of MyClass. Both calls to import will be pulling in the same instance.
You can confirm this by:
Putting some console logging in MyClass.js. Note that it only gets run once no matter how many times you import it.
Add a property to the object you import in one file (e.g. set auth.myFlag = true) and then check whether that flag is also present in the other file (i.e. check clsInstance.myFlag). This isn't totally conclusive but it's a pretty good way to verify that it's the same object rather than two separate instances.
If you wanted separate instances you might want to try exporting the class itself so that each file can create its own instance.
From the code you've posted I believe auth.isAuthenticated() and this.$auth.isAuthenticated() are calling the same method on the same object and (depending on what isAuthenticated does) should give the same result.

Using TypeScript with Dojo - import/export issues

In the company I work for we are using Dojo framework and lately I have started pushing to use it with TypeScript.
I took a look around and found this great article on how this topic, you can find it here:
https://gregwiechec.com/2016/01/creating-dojo-widget-in-typescript/
The last 2 lines in this solution are:
var exp = _declare("alloy.editors.StringListTs", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _CssStateMixin, _ValueRequiredMixin], new StringList());
export = exp;
I followed the same pattern and it works great, except for 2 issues that I cant seem to have a good solid solution:
1. If you look at the solution, when calling dojo declare method, the class created needs to be instantiated (this is because dojo looks at properties and not prototype).
2. The more problematic issue, is the fact that I am exporting out the dojo declared object, and not the class it self. This is problematic when you try to import the class (typescript import), and even if I declare the variable exp as the class type, I get an error saying that there is no constructor to what i am trying to import.
I faced your same problem, and for me has been a transpiler issue.
TL;DR if you import something using the import * as WidgetName from '<path>' syntax and don't use WidgetName in the js (like you would do for a widget in a template), the transpiler won't import it. Use import '<path>' instead.
Long answer: It's my first time with TypeScript and, similarly you, I'm converting a dojo project to TypeScript. Hoping to help more people, I'll put few steps which helped me to import modules correctly.
Step 0 dojoConfig packages
Defining you own package on dojoConfig won't work, modules must be referenced using relative path.
To be clear, with this example:
dojoConfig = {
...
packages : [ { name : "myproject", location : "js/myproject" },
{ name : "dojo", location : dojoBase+"dojo" },
{ name : "dijit", location : dojoBase+"dijit" },
{ name : "dojox", location : dojoBase+"dojox" } ]
};
It's not possible to have widget importing each other with import * as WidgetName from 'myproject/WidgetName' approach, but rather you have to import * as WidgetName from './WidgetName' (notice the '.' vs 'myproject').
Step 1: importing dojo declaration (not mandatory, as far as I noticed)
I'm relying on node, I pulled dojo-typing using npm install dojo-typings --save-dev. In the files property I specified [ "src/js/**/*.ts", "src/js/**/*.js", "node_modules/dojo-typings/dojo/1.11/index.d.ts", "node_modules/dojo-typings/dojo/1.11/modules.d.ts", "node_modules/dojo-typings/dijit/1.11/index.d.ts", "node_modules/dojo-typings/dijit/1.11/modules.d.ts" ].
Step 2: using the correct options on the transpiler:
{
"target": "es5",
"allowJs": true,
"module": "amd",
"moduleResolution": "classic",
"noImplicitUseStrict" : true
},
noImplicitUseStrict solved the error dojo/parser::parse() error TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them. allowJs allowed me to mix TypeScript and native dojo together.
Step 3: returning using export
This is an example of a very minimal module which doesn't require/import anything, but only exports a log method (file would be 'toast.ts'):
const log = function(message) {
window['dojo'].publish("mainTopic",
[{
message: "<span style='font-size: 12px;'>" + message +"</span>",
type: 'info',
duration: 3000
}]
);
}
export { log }
For completeness, in pure Dojo you would have written something like (file would be 'toast.js'):
define([ ],
function(){
var log = function(message) {
dojo.publish("mainTopic",
[{
message: "<span style='font-size: 12px;'>" + message +"</span>",
type: 'info',
duration: 3000
}]
);
};
return { log : log };
});
Step 4: rewrite your widget and import it correctly
I use a Main widget which takes all the body, here the content of Main.ts:
/// <amd-dependency path="dojo/text!./Main.html" name="template" />
declare var template: string;
import * as _Widget from 'dijit/_Widget';
import * as _TemplatedMixin from 'dijit/_TemplatedMixin';
import * as _WidgetsInTemplateMixin from 'dijit/_WidgetsInTemplateMixin';
import * as dojoDeclare from 'dojo/_base/declare';
import './MyVanillaJavascriptWidget';
import './MyModule';
import 'dojox/widget/Toaster';
import toast = require('./utility/toast');
export default dojoDeclare("mm.Main", [ _Widget, _TemplatedMixin, _WidgetsInTemplateMixin ], {
templateString : template,
});
There are different types of imports:
the first is the one I struggled the most, for the template
import * as ... is a sequence of dojo objects I use in the class
import '<path>' is used for widget I declared in the template using data-dojo-type
import name = require('<path>') is another way to require modules
For completeness, this would be the original Main.js file:
define([ "dijit/_Widget", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin",
"dojo/_base/declare", "dojo/text!./Main.html",
"dojox/widget/Toaster", "./MyVanillaJavascriptWidget", "./MyModule"
],
function( _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, declare, mainTemplate, toast) {
return declare("mm.Main", [ _Widget, _TemplatedMixin, _WidgetsInTemplateMixin ], {
templateString : mainTemplate,
});
});
Conclusion: The missing constructor most probably comes from the way you import a module, checking the transpiled code helped me to understand where the issue was. To succeed with the import, a bit of accuracy is needed here and there (all the steps above should give an overview).
I'm still in the process of converting my project (other issues may come out), but I hope this helps also other poor souls trying to use TypeScript with Dojo!

Access Store From Initializer in ember-cli

I have an initializer and the following is coming back as undefined:
container.lookup('store:main')
I am trying to implement this: http://say26.com/using-rails-devise-with-ember-js
Has anybody any ideas why this is?
Here is a code snippet on how I was able to inject the store into all components.
//initializers/general-setup.js
import Ember from 'ember';
//The intent of this file is to hold initializers
//that are general and lack specific context or scope
export default {
name: 'general-setup',
after: 'store',
initialize: function(container) {
container.injection('component', 'store', 'store:main');
}
};