Required Package in combination meteor+react+react-bootstrap - meteor

I used the following packages individually and combined
$ meteor add react
$ meteor add firfi:meteor-react-bootstrap
When I used the react package, bootstrap is not working.
If I use firfi:meteor-react-bootstrap, the react package is not working.
When I used both packages there is an error
Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's render method). Try rendering this component inside of a new top-level component which will hold the ref.
Can anyone suggest a package for react and react-bootstrap for meteor?
My Code:
var { Modal,Button,Input} = ReactBootstrap;
if (Meteor.isClient){
Meteor.startup(function () {
console.log("METEOR STARTUP");
React.render(<MyModal/>, document.getElementById('modal-container'));
});
}
var MyModal = React.createClass({
render: function() {
return (
<div className="modal-open">
<Modal
title='Modeltest'
backdrop={true}
animation={false}
closeButton={true}
onRequestHide={() => {}}>
<div className='modal-body'>
<p>Check the Modal body</p>
</div>
</Modal>
</div>
)
}
});

I have tried a few alternatives, and the set that works best for me today is:
react 0.1.13 Everything you need to use React with Meteor.
twbs:bootstrap 3.3.5 The most popular front-end framework for developing responsive, mobile first projects on the web.
universe:react-bootstrap 0.24.0 ReactBootstrap project wrapped for Meteor with Universe:modules
Version 0.24 is a bit old today, but you cannot use the latest React-Bootstrap anyway, since it requires React 0.14 which Meteor has not yet upgraded to. (See Meteor issue #116)

Related

how to use this.$refs in vue 3 composition api?

I use vue3-simple-html2pdf.
<vue3-simple-html2pdf ref="vue3SimpleHtml2pdf" :options="pdfOptions" :filename="exportFilename">
<div class="main-content">
<h1>PDF</h1>
</div>
</vue3-simple-html2pdf>
<button #click="download">Download pdf</button>
documentation says to do this when i want to download pdf
this.$refs.vue3SimpleHtml2pdf.download()
I use composition api and try to do like this
const vue3SimpleHtml2pdf = ref(null)
const download = () => {
vue3SimpleHtml2pdf.download()
}
but it doesn't work
how can I fix it?
Your code is not complete to understand how you have built your app. Vue App section is not shown.
UPDATE
Here is looks like you are trying to use the download() function from 'null'.
const vue3SimpleHtml2pdf = ref(null)
const download = () => {
vue3SimpleHtml2pdf.download()
}
This does not make any sense to me.
It looks like you are mixing ref() and $refs up. The first is the Special Attribute ref with access through the Vue App property $refs and the second is the ref() reactivity function. Please check the docs on how to use them.
The vue3-simple-html2pdf plugin has a great explanation page and a working sandbox app.
If you are not sure how to use the plugin with the Composition API, then I would suggest you to try to make your code work with the Options API using the sample from the Sandbox.
UPDATE 2
Please read the Docs on using the Composition API, starting from
Creating a Vue Application and especially Components Basics.
The Vue Tutorial Step 11. Components is also very helpful.
I forgot that I should refer to the
vue3SimpleHtml2pdf.value.download()
not to the
vue3SimpleHtml2pdf.download()
another solution is to call the function on click in the template
<button #click="this.$refs.vue3SimpleHtml2pdf.download()">Download pdf</button>

Markerclustererplus touch 'click' not working after today's maps update

I am using the Google Maps JavaScript API with markerclustererplus. I need markerclustererplus for its mouseover handler.
After today's Maps update, click is not longer functioning properly for touch screen devices. click works fine for laptop/desktops using a mouse/trackpad, but it is not longer working for touch screens.
I tried both the markerclustererplus libraries available, both are broken.
https://github.com/googlemaps/v3-utility-library/tree/master/markerclustererplus
https://github.com/mahnunchik/markerclustererplus
I tried the standard markerclusterer library as well, and it doesn't seem to be working either.
https://github.com/googlemaps/js-marker-clusterer
Everything was working fine before today's Maps update.
Does anyone have a fix for this?
EDIT:
I am using Django 1.11. On the frontend, I don't use any libraries apart from a bit of jQuery 3.2.1
There's not much to show with my code. It's pretty standard.
markerCluster = new MarkerClusterer(map, markers, clusterOptions);
markerCluster.addListener('click', function(cluster) {
markerClusterActivate(cluster);
});
function markerClusterActivate(cluster) {
... stuff that happens when cluster is clicked
}
So here is a workaround, you just roll back to google map 3.30
For vue.js projects.
https://github.com/xkjyeah/vue-google-maps/blob/v0.8.1/API.md
import Vue from 'vue'
import * as VueGoogleMaps from '~/node_modules/vue2-google-maps'
Vue.use(VueGoogleMaps, {
load: {
key: 'YOUR_API_KEY',
v: 'GOOGLE_MAPS_VERSION',
libraries: 'places' // Only if you need Autocomplete
}
})

Using Three.js with Meteor

I am trying to load the basic rotating cube example from the three.js getting started guide in to a basic meteor app:
http://threejs.org/docs/index.html#Manual/Introduction/Creating_a_scene
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.CubeGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
var render = function () {
requestAnimationFrame(render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
I have added this code into a template js manager file of a new meteor app and then call the render function on the render of my template:
Template.hello.rendered = function() {
if (!this._rendered) {
this._rendered = true;
render();
}
}
My template
<template name="hello">
<head>
<title>My first Three.js app</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
</body>
</template>
I have added three.js from atomosphere via:
mrt add three
and it loaded the package successfully into my app
However, when I start meteor I am getting an error that THREE is undefined.
I have tried moving three.js into the lib folder and that didn't work because I get an error that 'self' is undefined. I think this should only load as a client library. I have tried putting it with the client folder and below my manager file, but that didn't seem to work either and it seemed hacky. It seems like meteorite installed packages should be loaded first, right? WHy isn't this available from my template manager?
Any help would be greatly appreciated. I am new to both meteor and three.js so I think getting this basic demo working would really open my eyes.
Thanks!
Use the bower package and add three js through that.
https://atmospherejs.com/package/bower
I find that a lot of the wrapper packages on atmosphere fall out of date, so the bower package is a nice solution for this sort of thing.
The THREE.js library should go into client/compatibility folder. The package you were trying to use is probably deprecated.
EDIT
You can also try wrapping your THREEJS code with Meteor.startup to ensure the work is only performed after all js files are loaded. The Meteor's file loading order has always been a headake.
I really appreciate the feedback!
I also tried Bower and got a reference error on a new project after installing threejs package via Bower after starting Meteor. I am not sure what the issue is there.
However, I think I identified the problem with using three.js in the client folder. THREE is defined with VAR so only has local file scope and was not available from my manager file. There is a newer atmosphere package that has modified this to use a global scope:
https://atmospherejs.com/package/three.js
This package works. I found that you can also use the newest min.three.js file directly in the client folder without installing a package if you add window.THREE = THREE; to the end of the file--giving the local THREE variable access to global scope.
Finally, it's worth mentioning that I had defined my 'var scene' and other three.js code as shown in my question outside of the if Meteor.isClient function. Since my three.js code was within the client folder and inaccessible to the server, the server was throwing this error.
I hope someone finds my pitfalls helpful. Meteor definitely requires a slightly new way of looking at a JS appilcation, but I think it will be really great. I am excited to move past this seemingly simple issue that has been driving me crazy.

How do I switch Bootswatch themes in Meteor?

I am building an app for the first time using Meteor. Due to an accessibility issue, we would like to offer two different Bootswatch themes to the users. I found a very useful explanation of how to switch Bootswatch themes here:
How to dynamically change themes after clicking a drop down menu of themes
(which references a handy fiddle in the accepted answer: http://jsfiddle.net/82AsF/)
I have tried placing the provided javascript inside myapp.html in the <head> tag. I also tried placing it inside the myapp.js file. (Then I tried placing in many assorted places just to see what would happen ;-) )
Nothing I have tried is working and it seems that it is the Meteor framework that is, understandably, "getting in the way". Is there an approach that will work for switching Bootswatch themes in a Meteor app?
Dynamically switching bootswatch themes is easily done as demonstrated in the originally referenced question: How to dynamically change themes after clicking a drop down menu of themes
Meteor (plus iron-router in my case) complicates this a little through the event maps and the simple fact that the dynamic change is occurring in the <head>.
Another answered question explains how to handle an event in jQuery directly (bypassing Meteor event maps): How to handle custom jQuery events in Meteor?
The code snippet below shows how I put the two ideas together. It's all working as expected.
var themes = {
"default": "bootstrap311/css/bootstrap.default.min.css",
"readable" : "bootstrap311/css/bootstrap.readable.min.css",
"slate" : "bootstrap311/css/bootstrap.slate.min.css"
}
$(function(){
var themesheet = $('<link href="'+themes['default']+'" rel="stylesheet" />');
themesheet.appendTo('head');
$('body').on('click', '.theme-link', function (e) {
var themeurl = themes[$(this).attr('data-theme')];
themesheet.attr('href',themeurl);
});
});

Using third party javascript package with Meteor

I'm working with Meteor at the moment, and I'm trying to make it look more 'real timey' by adding transitions to numbers as they change. The best third party package I can see for that is http://github.hubspot.com/odometer/.
I'm having trouble getting the package to work in Meteor to update comment numbers on an item.
I've tried putting the javascript into client/compatibility as per the meteor docs: http://docs.meteor.com/#structuringyourapp, but no joy.
The other issue might be that the package uses CSS transitions, which would mean that a re-rendering of the template around the number that is updating would prevent the transition from occurring. To try and fix this problem, I used {{#isolate}} around the number, but that didn't work either.
Has anyone got any other ideas on what else in meteor might be getting in the way?
I think you should try {{#constant}} instead of {{#isolate}}. Also note, that the "constant" part of your template will no longer be reactive, so you'll have to update it manually. Supposing that you have a template
<template name="myTemplate">
{{#constant}}
<span class="odometer"></span>
{{/constant}}
</template>
you will need to do something like this:
Template.myTemplate.rendered = function () {
var node = this.find('.odometer');
Deps.autorun(function () {
node.innerHtml = MyCollection.find({}).count();
});
}

Resources