Can't Wait Without A Fiber - meteor

Meteor Version: 1.2.1
Using Base Framework from themeteorchef
And using a package themeteorchef:seeder
When I tried to use the seeder package in a clean new project (without the base starter), it works fine. However in my project created from the base starter, it throws Can't Wait Without A Fiber Error in the part of the code that calls the Seed function.
The same thing happened to me when I try to call database functions like find and insert. I enclosed the code inside a Fiber function after adding fibers to the list of my app.use libraries in my package.js
Here is my package.js file
Package.describe({
name: 'team:library',
version: '0.0.1',
// Brief, one-line summary of the package.
summary: '',
// URL to the Git repository containing the source code for this package.
git: '',
// By default, Meteor will default to using README.md for documentation.
// To avoid submitting documentation, set this field to null.
documentation: 'README.md'
});
Npm.depends({
library: "link-to-a-github-commit",
util: '0.10.3'
});
Package.onUse(function(api) {
api.versionsFrom('1.2.1');
api.use(['ecmascript', 'templating', 'check', 'mongo', 'kadira:flow-router', 'themeteorchef:seeder', 'fibers']);
// Load the lib directory before all other files are loaded
api.addFiles( 'lib/constants/tokens.js', 'server' );
api.addFiles('client/templates/library-widget.html', 'client');
api.addFiles('client/templates/library-widget.js', 'client');
api.addFiles('client/templates/user-folder-list-widget.html', 'client');
api.addFiles('client/templates/user-folder-list-widget.js', 'client');
api.addFiles('client/templates/index.html', 'client');
api.addFiles( 'collections/LibraryUsers.js', 'server' );
api.export( 'LibraryUsers', 'server' );
api.addFiles('server/startup.js', 'server');
api.addFiles('server/methods/library-team.js', 'server');
});
Package.onTest(function(api) {
api.use('ecmascript');
api.use('tinytest');
api.use('team:library');
api.addFiles('library-tests.js');
});
And I am calling Seed in my server/startup.js file inside my package as follows:
Seed( 'Products', {
min: 5,
environments: [ 'development', 'staging', 'production' ],
model( index ) {
return {
name: faker.commerce.product(),
price: faker.commerce.price()
};
}
});
And I enclosed it inside Fiber as follows
try {
Fiber( function() {
Seed( 'Products', {
min: 5,
environments: [ 'development', 'staging', 'production' ],
model( index ) {
return {
name: faker.commerce.product(),
price: faker.commerce.price()
};
}
});
});
} catch( error ) {
console.log( error );
}
after including fibers in my package file as shown in the package file above. And the error message I get is
[ReferenceError: Fiber is not defined]
What could have caused this error?

Putting the following line before your 'Fiber( function() { ...' probably resolves that error, as it defines the 'Fiber' object that you're using:
Fiber = Npm.require('fibers');
or simply this might also work, not sure:
Fiber = require("fibers")

Related

How to connect google analytics to Nuxt3 app?

I have a problem. I try to connect my Nuxt3 app with Google Analytics.
right now I do it by adding to nuxt.config.ts following code
export default defineNuxtConfig({
buildModules: [
'#nuxtjs/google-analytics'
],
googleAnalytics: {
id: process.env.GOOGLE_ANALYTICS_ID
},
})
but unfortunately I get following error when I try to build my app
ERROR Error compiling template: { 17:53:04
ssr: false,
src: 'C:\\Users\\szczu\\Elektryk\\node_modules\\#nuxtjs\\google-analytics\\lib\\plugin.js',
fileName: 'google-analytics.js',
options: {
dev: true,
debug: {
sendHitTask: true
},
id: undefined
},
filename: 'google-analytics.js',
dst: 'C:/Users/szczu/Elektryk/.nuxt/google-analytics.js'
}
ERROR serialize is not defined 17:53:04
at eval (eval at <anonymous> (node_modules\lodash.template\index.js:1550:12), <anonymous>:7:1)
at compileTemplate (/C:/Users/szczu/Elektryk/node_modules/#nuxt/kit/dist/index.mjs:493:45)
at async /C:/Users/szczu/Elektryk/node_modules/nuxt3/dist/chunks/index.mjs:1296:22
at async Promise.all (index 11)
at async generateApp (/C:/Users/szczu/Elektryk/node_modules/nuxt3/dist/chunks/index.mjs:1295:3)
at async _applyPromised (/C:/Users/szczu/Elektryk/node_modules/perfect-debounce/dist/index.mjs:54:10)
Does anyone have an idea how to fix it?
Try the vue-vtag-next package as a plugin
yarn add --dev vue-gtag-next
Create a plugin file plugins/vue-gtag.client.js
import VueGtag from 'vue-gtag-next'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(VueGtag, {
property: {
id: 'GA_MEASUREMENT_ID'
}
})
})
Late reply, but i would like to add for any future viewers.
The above solution only worked for me when the $router was passed. Please find below sample code.
Please also note:
The package being used, 'vue-gtag' instead of 'vue-gtag-next'.
You have to pass config object instead of property for the 'vue-gtag' package
import VueGtag from 'vue-gtag'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(VueGtag, {
config: {
id: 'GA_MEASUREMENT_ID',
},
}, nuxtApp.$router)
})
found this solution https://github.com/nuxt/framework/discussions/5702
.. And also you may use nuxt.config to provide app.head.script with children attribute on the app level:
import { defineNuxtConfig } from "nuxt";
export default defineNuxtConfig({
app: {
head: {
script: [{ children: 'console.log("test3");' }],
},
},
});
import VueGtag from 'vue-gtag-next'
export default defineNuxtPlugin(async (nuxtApp) => {
const { data: { value: {google_id, google_sv, yandex_id, privacy_policy} } } = await useMyApi("/api/main/site-metriks/");
nuxtApp.vueApp.use(VueGtag, {
property: {
id: google_id
}
})
})
For Nuxt 3:
Install vue-gtm: npm i #gtm-support/vue-gtm
Create file in /plugins/vue-gtm.client.ts
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(createGtm({
id: 'GTM-ID',
defer: false, // Script can be set to `defer` to speed up page load at the cost of less accurate results (in case visitor leaves before script is loaded, which is unlikely but possible). Defaults to false, so the script is loaded `async` by default
compatibility: false, // Will add `async` and `defer` to the script tag to not block requests for old browsers that do not support `async`
nonce: '2726c7f26c', // Will add `nonce` to the script tag
enabled: true, // defaults to true. Plugin can be disabled by setting this to false for Ex: enabled: !!GDPR_Cookie (optional)
debug: true, // Whether or not display console logs debugs (optional)
loadScript: true, // Whether or not to load the GTM Script (Helpful if you are including GTM manually, but need the dataLayer functionality in your components) (optional)
vueRouter: useRouter(), // Pass the router instance to automatically sync with router (optional)
//ignoredViews: ['homepage'], // Don't trigger events for specified router names (optional)
trackOnNextTick: false, // Whether or not call trackView in Vue.nextTick
}))
})
Nuxt would automatically pick up this plugin and you're done.

How to properly build an AMD app as a single file with r.js using grunt?

I keep seeing this error when executing the compiled file:
Uncaught Error: No json
Here's my current requirejs grunt task configuration:
requirejs: {
options: {
baseUrl: "build/repos/staging/dev",
mainConfigFile: "dev/main.js",
generateSourceMaps: false,
preserveLicenseComments: false,
name: "almond",
out: "./static/js/compiled.js",
//excludeShallow: ['vendor'],
findNestedDependencies: true,
removeCombined: true,
//wrap: true,
optimize: "uglify2",
uglify2: {
output: {
beautify: true,
},
lint: true,
mangle: false,
compress: false,
compress: {
sequences: false
}
}
}
}
And here's my dev/main.js file:
// This is the runtime configuration file.
// It also complements the Gruntfile.js by supplementing shared properties.require.config({
waitSeconds: 180,
urlArgs: 'bust=' + (new Date()).getTime(),
paths: {
"underscore": "../vendor/underscore/underscore",
"backbone": "../vendor/backbone/backbone",
"layoutmanager": "../vendor/layoutmanager/backbone.layoutmanager",
"lodash": "../vendor/lodash/lodash",
"ldsh": "../vendor/lodash-template-loader/loader",
"text": "../vendor/requirejs-plugins/lib/text",
"json": "../vendor/requirejs-plugins/json",
"almond": "../vendor/almond/almond",
// jquery
"jquery": "../vendor/jquery/jquery",
"jquery.transit": "../vendor/jquery.transit/jquery.transit",
"jquery.mousewheel": "../vendor/jquery.mousewheel/jquery.mousewheel",
"jquery.jscrollpane": "../vendor/jquery.jscrollpane/jquery.jscrollpane"
},
shim: {
'backbone': {
deps: ['underscore']
},
'layoutmanager': {
deps: ['backbone', 'lodash', 'ldsh']
},
'jquery.transit': {
deps: ['jquery']
},
'json': {
deps: ['text']
}
}});
// App initialization
require(["app"], function(instance) {
"use strict";
window.app = instance;
app.load();
});
And finally, my dev/app.js file:
define(function(require, exports, module) {
"use strict";
// External global dependencies.
var _ = require("underscore"),
$ = require("jquery"),
Transit = require('jquery.transit'),
Backbone = require("backbone"),
Layout = require("layoutmanager");
module.exports = {
'layout': null,
'load': function() {
var paths = [
// ***
// *** 1- define its path
// ***
'json!config/main.json',
'modules/nav',
'modules/store',
'modules/utils',
'modules/preloader',
'modules/popup',
'modules/login',
'modules/user',
'modules/footer',
];
try {
require(paths, function(
// ***
// *** 2- call it a name
// ***
Config,
Nav,
Store,
Utils,
Preloader,
Popup,
Login,
User,
Footer
) {
// ***
// *** 3- instance it in the app
// ***
app.Config = Config;
app.Nav = Nav;
app.Store = Store;
app.Utils = Utils;
app.Preloader = Preloader;
app.Popup = Popup;
app.Login = Login;
app.User = User;
app.Footer = Footer;
// require and instance the router
require(['router'], function(Router) {
// app configuration
app.configure();
// app initialization
app.Router = new Router();
});
});
} catch (e) {
console.error(e);
}
},
'configure': function() {
var that = this;
// set environment
this.Config.env = 'local';
// Ajax global settings
Backbone.$.ajaxSetup({
'url': that.Config.envs[that.Config.env].core,
'timeout': 90000,
'beforeSend': function() {
},
'complete': function(xhr, textstatus) {
}
});
// Template & layout
_.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
};
Layout.configure({
// Allow LayoutManager to augment Backbone.View.prototype.
manage: true,
// Indicate where templates are stored.
prefix: "app/templates/",
// This custom fetch method will load pre-compiled templates or fetch them
// remotely with AJAX.
fetch: function(path) {
// Concatenate the file extension.
path = path + ".html";
// If cached, use the compiled template.
if (window.JST && window.JST[path]) {
return window.JST[path];
}
// Put fetch into `async-mode`.
var done = this.async();
// Seek out the template asynchronously.
$.get('/' + path, function(contents) {
window.JST[path] = contents;
done(_.template(contents));
}, "text");
}
});
},
};
});
Any ideas why is that json module not "required" when executing grunt requirejs ?
Thanks in advance.
Not sure if this is still an issue, but from the requirejs optimizer docs (http://requirejs.org/docs/optimization.html):
The optimizer will only combine modules that are specified in arrays of string literals that are passed to top-level require and define calls, or the require('name') string literal calls in a simplified CommonJS wrapping. So, it will not find modules that are loaded via a variable name...
It sounds like the requirejs optimizer doesn't like the require calls being made with a variable that is an array of dependencies.
It also sounds like the requirejs optimizer doesn't like the syntax of require([dependency array], callback) being used within the actual file being optimized.
You may have to refactor your dependency declarations within dev/app.js to conform to this specification. For example, you might be able to use the following refactoring of steps 1 and 2:
var Config = require('json!config/main.json');
var Nav = require('modules/nav');
var Store = require('modules/store');
var Utils = require('modules/utils');
var Preloader = require('modules/preloader');
var Popup = require('modules/popup');
var Login = require('modules/login');
var User = require('modules/user');
var Footer = require('modules/footer');
If this does work, it looks like you'll also have to do something similar for the Router dependency declaration.
Also, a minor addition that you might want to include to your requirejs configuration once you get it running is:
stubModules : ['json']
Since the built file should have the JSON object within it, you won't even need the plugin within the built file! As such, you can reduce your file size by removing the json plugin from it.

Location of Intern reporters output files like corbertura or html report

I'm using Grunt with Intern and set some reporters to lcovhtml and cobertura:
grunt.initConfig({
intern: {
runner: {
options: {
config: 'tests/intern',
runType: 'runner',
reporters: ['pretty', 'lcovhtml','junit','cobertura']
}
}
},
Is there any configuration to control output directory of these files for all or each reporter?
For example, by adding a parameters reportDir to the options object defined in your Gruntfile.js, you can update intern/lib/reporters/lcovhtml.js with:
define([
'dojo/node!istanbul/lib/collector',
'dojo/node!istanbul/lib/report/html',
'dojo/node!istanbul/index'
], function (Collector, Reporter) {
var collector = new Collector(),
reporter = new Reporter();
//...
});
with:
define([
'../args',
'dojo/node!istanbul/lib/collector',
'dojo/node!istanbul/lib/report/html',
'dojo/node!istanbul/index'
], function (args, Collector, Reporter) {
var collector = new Collector(),
reporter = new Reporter({ dir: args.reportDir });
//...
});
You can propagate a similar update in cobertura.js and junit.js reporters.
Note: I documented this approach in https://github.com/theintern/intern/issues/71. The patch for the corresponding issue has not yet been published (pushed to Intern 2.3).

Meteor Packages: How to use different CSS based on 'development' or 'production'

There are some CSS #import statements in our code that really slow down Meteor's auto-reload.
I would like to take these out, but only for development.
Inside a Meteor package, neither of the following variables:
process.env.NODE_ENV
Meteor.settings
is accessible.
Package.describe({
name: 'a-package',
version: '0.0.1'
});
Package.onUse(function (api) {
api.versionsFrom('1.0.2.1');
// ...
if(???) {
api.addFiles('development-fonts.css');
}
else {
api.addFiles('production-fonts.css');
}
});
The best way we figured to do it was this:
When starting meteor in development:
`FAST=1 meteor`
Then, inside package.js:
if(!!process.env.FAST) {
api.addFiles('raisal-dash-common-fonts-development.css', 'client');
} else {
api.addFiles('raisal-dash-common-fonts-production.css', 'client');
}

Spiderable and Iron-Router example

Does someone uses Iron-Router and Spiderable-404?
Please I need some complete examples to show me how to add the metatags.
They say this:
if (Meteor.isClient) {
Meteor.Router.add({
'/': 'index',
'/a': 'a',
'/b': function() {
Spiderable.httpHeaders['X-Foo'] = 'bar';
return 'b';
},
'*': function() {
Spiderable.httpStatusCode = 404;
return 'notFound';
}
});
}
but this does not work in iron router and there is no meta tag in this poor example, or I could not make it work, please help me fill the blanks.
The spiderable package is just a package you install and forget in Meteor. You do not use it directly from within your app.
Meteor SEO is not very mature, but you have options to get basic SEO working. Especially when you are using iron-router, there is the ms-seo smart package that you can use as:
$ mrt add ms-seo
and then in your router configuration:
Router.map(function() {
return this.route('blogPost', {
path: '/blog/:slug',
waitOn: function() {
return [Meteor.subscribe('postFull', this.params.slug)];
},
data: function() {
var post;
post = Posts.findOne({
slug: this.params.slug
});
return {
post: post
};
},
onAfterAction: function() {
var post;
// The SEO object is only available on the client.
// Return if you define your routes on the server, too.
if (!Meteor.isClient) {
return;
}
post = this.data().post;
SEO.set({
title: post.title,
meta: {
'description': post.description
},
og: {
'title': post.title,
'description': post.description
}
});
}
});
});
Also for 404 responses, iron-router's standard notFoundTemplate already provides the HTTP status code out of box. For other status codes, you need to define server side routes
````
Router.map(function () {
this.route('serverFile', {
where: 'server',
path: '/files/:filename',
action: function () {
var filename = this.params.filename;
this.response.writeHead(200, {'Content-Type': 'text/html'});
this.response.end('hello from server');
}
});
});
````
PS: You may want to refer to this blog post, and this one for further reading.
PPS: Your router configuration looks generally wrong. Your code looks like it belongs to the outdated meteor-router package. Refer to the iron-router package docs for more information.

Resources