Override meanjs routes without overwriting meanjs code - meanjs

The meanjs core module provides a default index page for the home state:
// Home state routing
$stateProvider
.state('home', {
url: '/',
templateUrl: 'modules/core/client/views/home.client.view.html'
})
I have added my own module mymod to the meanjs application. I would like to use my own partial modules/mymod/client/views/browse.client.view.html.
How do I do it WITHOUT modifying the core.client.route.js file? I always avoid modifying code obtained from frameworks and belive in overriding. What is the recommended approach to do this?

I think you are misunderstanding the point of MEANJS. From MEANJS github page:
MEAN.JS is a full-stack JavaScript open-source solution, which provides a solid starting point for MongoDB, Node.js, Express, and AngularJS based applications. The idea is to solve the common issues with connecting those frameworks, build a robust framework to support daily development needs, and help developers use better practices while working with popular JavaScript components.
MEANJS is not a strict platform that will stop working if you change its own code. Of course that there are some code blocks that should not be modified but there are blocks that you can/should modify to avoid clutter in your code as your app grows.
With that said, you can still keep the route as it is:
$stateProvider
.state('home', {
url: '/',
templateUrl: 'modules/core/client/views/home.client.view.html'
});
And in this partial modules/core/client/views/home.client.view.html, you can use AngularJS directive ng-include and in the src put the path for your custom partial browse.client.view.html. This way you don't need to modify core.client.route.js you just have to modify the partial modules/core/client/views/home.client.view.html.

Related

Lazy load web-components from other services in polymer 3

I have a microservice based application and each service has a set of polymer based web-components. I want to load these at runtime in the application that is served by one of them at runtime, so that I can run, maintain and deploy the services seperately.
I would like to avoid having a npm repo that serves the components for a central build and each new web component version would make it necessary to rebuild and redeploy the application.
Existing lazy loading examples all lazy load components of the same application, so it's built as a whole and just packaged in chunks.
The application is available under /app/ and the modules are under /mod/...
I can do this in to react to a route:
import('/mod/admindashboard/kw-admindashboard.js').then((module) => {
// Put code in here that you want to run every time when
// navigating to view1 after my-view1.js is loaded.
console.log("Loaded admindashboard");
});
and then I can use the corresponding web component, but for this to work I need to hack the component like this:
import { PolymerElement, html } from '/app/node_modules/#polymer/polymer/polymer-element.js';
import '/app/node_modules/#polymer/iron-icon/iron-icon.js';
import '/app/node_modules/#polymer/iron-icons/iron-icons.js';
class KwAdmindashboard extends PolymerElement {
static get template() {
...
But this approach prevents me completely to run tests, create static builds and IDE support is not available either in many areas, as it's not able to see what is available later at runtime. So as absolute fallback this would be possible. Isn't there a way to utilize the serviceWorkers to handle mapping?
Here below is I think a good example of your requirement. Modules will be loaded with page properties. As page property is depended on iron-page, selected='{{page}}' when page value has been changed with iron-page's name properties, its observer loads the that page's modules. :
static get properties() { return {
page: {
type: String,
reflectToAttribute: true,
observer: '_pageChanged'
},
.......
_pageChanged(page, oldPage) {
if (page != null) {
let cb = this._pageLoaded.bind(this, Boolean(oldPage));
// HERE BELOW YOUR PAGE NAMES
switch (page) {
case 'list':
import('./shop-list.js').then(cb);
break;
case 'detail':
import('./shop-detail.js').then(cb);
break;
case 'cart':
import('./shop-cart.js').then(cb);
break;
case 'checkout':
import('./shop-checkout.js').then(cb);
break;
default:
this._pageLoaded(Boolean(oldPage));
}
here above cb is a function which is loading lazy modules but needs to load immediately after the first render. Which is minimum required files.
_pageLoaded(shouldResetLayout) {
this._ensureLazyLoaded();
}
Here the full code's link of the above. Hope this helps In case of any question I will try to reply. https://github.com/Polymer/shop/blob/master/src/shop-app.js
It seems like Polymer 3 is not yet ready for distributed locations of webcomponents.
There are github issues at the W3C which may solve these problems:
https://github.com/w3c/webcomponents/issues/716
Web component registries for really distributed component development without clashes due to namespaced component registration
https://github.com/domenic/import-maps
introduces a mapping from "nopm module names" to locations, which enables runtime binding much easier
For now I will switch my development model, so the microservices provide one or more webcomponents to my npm repo in nexus and the admin app has build time dependencies to them and builds the whole app in one go and there I can use the lazy loading approach that the shop demo also promotes/shows.
For a decent development experience with webcomponents from multiple sources, you should have a look at "npm link".
Feel free to add another solution for the problem or a real solution as soon as the technology and standards caught up.

Vuejs endpoint configuration

I'm really new in VueJS,
I use RxJS, Vue rx and Vue Resource in a mixin so i can make http calls and get observables back anywhere... awesome!
now i tried
subscriptions () {
return {
titles$: this.getHTTPObservable('https://jsonplaceholder.typicode.com/albums').flatMap(arr => Rx.Observable.from(arr).take(10).map(o => o.title).toArray())
}
The only thing i need now is to specify the end point of the server i am requesting in some configuration file like i would do in angular environments file. When launching the build by hand it should look like when i write
ng serve --env=dev
is there something similar?
Actually i found the answer on this page https://vuejs-templates.github.io/webpack/env.html
so, i can add any configuration variable and then call process.env.varname to get it back,
thanks
Vue.js normally works in conjunction with Webpack to achieve this.
https://v2.vuejs.org/v2/guide/deployment.html#With-Build-Tools
The DefinePlugin from Webpack is used for this. Outside of Webpack I think you are still able to use this:
https://www.npmjs.com/package/cross-env

Using ES6 `import` with CSS/HTML files in Meteor project: bug or feature?

I am currently learning Meteor and I found out something that intrigued me.
I can load HTML and CSS assets from a JS file using the import statement.
import '../imports/hello/myapp.html';
import '../imports/hello/myapp.css';
import * as myApp from '../imports/hello/myapp.js';
This was a surprise to me so I ran to google but could not find this behavior documented in the specification for ES6 import or in Meteor's Docs.
So my questions are:
Can I rely on this behavior to build my apps?
Will my app will break when Meteor gets around to fix it -- if it's a bug --?
Notes
I am using Meteor v1.3, not sure if this works also with previous versions.
You can download the app to see this behavior from Github
After going through the implementation of the built files for my app
I found out why this works.
HTML
Files are read from the file system and their contents added to the global Template object, e.g.,
== myapp.html ==
<body>
<h1>Welcome to Meteor!</h1>
{{> hello}}
</body>
results in the following JS code:
Template.body.addContent((function () {
var view = this;
return [
HTML.Raw("<h1>Welcome to Meteor!</h1>\n\n "),
Spacebars.include(view.lookupTemplate("hello"))
];
}));
Which is wrapped in a function with the name of the file as it's key:
"myapp.html": function (require, exports, module) {
Template.body.addContent((function () {
var view = this;
return [
HTML.Raw("<h1>Welcome to Meteor!</h1>\n\n "),
Spacebars.include(view.lookupTemplate("hello"))];
}));
Meteor.startup(Template.body.renderToDocument);
Template.__checkName("hello");
Template["hello"] = new Template("Template.hello", (
function () {
var view = this;
return [
HTML.Raw("<button>Click Me</button>\n "),
HTML.P("You've pressed the button ",
Blaze.View("lookup:counter",
function () {
return Spacebars.mustache(view.lookup("counter"));
}), " times.")
];
}));
},
So all of our HTML is now pure JS code which will be included by using require like any other module.
CSS
The files are also read from the file system and their contents are embedded also in JS functions, e.g.
== myapp.css ==
/* CSS declarations go here */
body {
background-color: lightblue;
}
Gets transformed into:
"myapp.css": ["meteor/modules", function (require, exports, module) {
module.exports = require("meteor/modules").addStyles("/* CSS declarations go here */\n\nbody {\n background-color: lightblue;\n}\n");
}]
So all of our CSS is also now a JS module that's again imported later on by using require.
Conclusion
All files are in one way or another converted to JS modules that follow similar rules for inclusion as AMD/CommonJS modules.
They will be included/bundled if another module refers to them. And since all of them are transformed to JS code
there's no magic behind the deceitful syntax:
import '../imports/hello/myapp.html';
import '../imports/hello/myapp.css';
They both are transpiled to their equivalent forms with require once the assets have been transformed to JS modules.
Whereas the approach of placing static assets in the imports directory is not mentioned in the official documentation,
this way of importing static assets works.
This seems to be at the core of how Meteor works so I'd bet this functionality is going to be there for a long while.
I don't know if to call this a feature maybe a more appropriate description is unexpected consequence but that would
only be true from the user's perspective, I assume the people who wrote the code understood this would happen and perhaps even
designed it purposely this way.
One of the features in Meteor 1.3 is lazy-loading where you place your files in the /imports folder and will not be evaluated eagerly.
Quote from Meteor Guide:
To fully use the module system and ensure that our code only runs when
we ask it to, we recommend that all of your application code should be
placed inside the imports/ directory. This means that the Meteor build
system will only bundle and include that file if it is referenced from
another file using an import.
So you can lazy load your css files by importing them from the /imports folder. I would say it's a feature.
ES6 export and import functionally are available in Meteor 1.3. You should not be importing HTML and CSS files if you are using Blaze, the current default templating enginge. The import/export functionality is there, but you may be using the wrong approach for building your views.

will gulp have an issue compiling javascript 1.7 object destructing syntax?

I have seen this "destructing" syntax before but haven't ever used it. until now anyways. I want to pull in a react-router repo on github to handle my applications routing (making a single page app). but I noticed that it has this syntax
var { Route, RouteHandler, Link } = Router;
which is just a fancy way of writing
var Route = Router.Route
var RouteHandler = Router.RouteHandler
var Link = Router.Link
so my question is does anyone know if gulp will have any issues compiling this from jsx to javascript?
Do I need to install any additional dependencies for this syntax?
I have done some research but couldn't find anything conclusive. Thanks
The default gulp, yes. JSX syntax needs to be transpiled down to native js. Take a look at gulp-react to see how you can deal with this. Basically , it works in similar concept to other transpiled code (ie. coffeescript). Convert to native before piping along to the next task.
Edit
after seeing you're edit, it looks like you also need to convert the ES6. Take a look at the react browserify, it should help to get you going. Basically the concept is the same, compile jsx/es6 to native js. There's a section specific to the ES6 react components.
2nd Edit
Looks like gulp-react has an option to set to ES6. I think if you add this line, it will work.
.pipe(react({harmony: true}))
//full example
gulp.task('default', function () {
return gulp.src('template.jsx')
.pipe(react({harmony: true))
.pipe(gulp.dest('dist'));
});

How to achieve async routing with app-router in polymer application?

I need to check if the user is logged in prior to rendering the route's import - so async. I know flatiron-director supports this but how would it be achieved with app-router (https://github.com/erikringsmuth/app-router)?
Look at this issue, it might be helpful