I like to fix the cross brower sync in https://github.com/broerse/ember-cli-blog. If I swap out the adapter for a Firebase adapter everything works as expected. (See https://github.com/broerse/ember-cli-blog-fire) It can be some CouchDB setup error on my side but there are no errors in the console. Is there some simple thing I keep overlooking?
Modified the ember-pouch readme to fix this, but to answer here: what you need to do is add
afterModel: function (recordArray) {
// This tells PouchDB to listen for live changes and
// notify Ember Data when a change comes in.
new PouchDB('mydb').changes({
since: 'now',
live: true
}).on('change', function () {
recordArray.update();
});
}
Related
I am developing a Point of sale (POS) for my store. And I am developing a Meteor app that will connect to the POS receipt printer. But as you know you cant simply use window.print().
I read but didnt understand the Meteor documentation about this, and I have several questions about it. (https://guide.meteor.com/mobile.html#using-plugins)
I have installed the katzer/cordova-plugin-printer (https://github.com/katzer/cordova-plugin-printer). And know here comes the questions.
1.- Once installed, I create a file outside the server and client folder and insert a statement such as
if (Meteor.isCordova) {
console.log("Printed only in mobile Cordova apps");
}
and then do I simply add the following line?
if (Meteor.isCordova) {
document.addEventListener('deviceready', function () {
// cordova.plugins.printer is now available
}, false);
}
2.- If this is correct, Do I create a Meteor Method in the server or in Meteor.isCordova? to call the following example.
var page = '<h1>Hello Document</h1>';
cordova.plugins.printer.print(page, 'Document.html');
3.- Should I use server side rendering to create the
var page = '<h1>Hello Document</h1>';
part.
Thank you
To answer your points:
Meteor.startup is run when the device or browser is ready (it's equivalent to what you are doing).
Create a method in the client code - Put the check in the button click method. Something like the code block at the end
Server side rendering won't apply as you are printing from the browser
if (Meteor.isCordova) {
Meteor.call("myPrintMethod",other-info);
} else {
alert("Sorry, I can only print from the device"
}
How can I let the user know when they are getting a hot code push?
At the moment the screen will go blank during the push, and the user will feel it's rather weird. I want to reassure them the app is updating.
Is there a hook or something which I can use?
Here's the shortest solution I've found so far that doesn't require external packages:
var ALERT_DELAY = 3000;
var needToShowAlert = true;
Reload._onMigrate(function (retry) {
if (needToShowAlert) {
console.log('going to reload in 3 seconds...');
needToShowAlert = false;
_.delay(retry, ALERT_DELAY);
return [false];
} else {
return [true];
}
});
You can just copy that into the client code of your app and change two things:
Replace the console.log with an alert modal or something informing the user that the screen is about to reload.
Replace ALERT_DELAY with some number of milliseconds that you think are appropriate for the user to read the modal from (1).
Other notes
I'd recommend watching this video on Evented Mind, which explains what's going on in a little more detail.
You can also read the comments in the reload source for further enlightenment.
I can image more complex reload logic, especially around deciding when to allow a reload. Also see this pacakge for one possible implementation.
You could send something on Meteor.startup() in your client-side code. I personally use Bert to toast messages.
I have a pretty standard setup for my meteor app using IronRouter. What I am having problems with is this, I am attempting to redirect someone to a page based on some tokens in a url coming from a third party website but when the user is sent to their destination from the Accounts.onLogin callback via Router.go("some/fun/url"); the waitOn function runs endlessly.
Below is the pertinent part of the setup.
First the route that I am redirecting to:
Router.route("/shows/:show_acronym/sponsorships", {
name:"sponsorshipsSalesPortal",
data:function(){
return {show:Shows.findOne({acronym:this.params.show_acronym})};
},
waitOn:function(){
console.log("wait on");
return [Meteor.subscribe("show_by_acronym",this.params.show_acronym),Meteor.subscribe("catalogue_products_by_acronym", this.params.show_acronym)];
}
});
Next the relevant part of the onLogin hook:
Accounts.onLogin(function(){
if (Session.get("showToRedirectTo")){
console.log("sending to sponsorship portal");
var ur ="/shows/"+Session.get("showToRedirectTo")+"/sponsorships"
return Router.go(ur);
}
});
When it hits the redirect, the url changes and the message "wait on" prints in the console forever. Does anyone know of a solution to this? I would prefer to keep all of my subscriptions at the router level if at all possible.
Thanks
You should only return subscription cursors (Meteor.subscribe(*)) in the waitOn return array.
In your case, "this.params.show_acronym" is the problem...
Actually your code looks good, its been a while since i dont use Iron Router or Sessions.
But looking at the WaitOn, it seems okay, the problem can come from the Server side where show_by_acronym or catalogue_products_by_acronym its throwing an error, but in all the cases this should cause you to get a spinner loading forever, not a console.log("wait on"); printed forever.
so i think your Accounts.onLogin is causing this.
Try something like.
Accounts.onLogin(function(){
if (Session.get("showToRedirectTo")){
console.log("sending to sponsorship portal");
var ur ="/shows/"+Session.get("showToRedirectTo")+"/sponsorships"
Router.go(ur);
Session.set('showToRedirectTo', false)
}
});
I'd like to use the utilities:avatar package, but I'm having some major reservations.
The docs tell me that I should publish my user data, like this:
Meteor.publish("otherUserData", function() {
var data = Meteor.users.find({
}, {
fields : {
"services.twitter.profile_image_url_https" : true,
"services.facebook.id" : true,
"services.google.picture" : true,
"services.github.username" : true,
"services.instagram.profile_picture" : true
}
});
return data;
});
If I understand Meteor's publish/subscribe mechanism correctly, this would push these fields for the entire user database to every client! Clearly, this is not a sustainable solution. Equally clearly, however, either I am doing something wrong, or I am understanding something wrong.
Also: This unscalable solution works fine in a browser, but no avatar icons are visible when the app is deployed to a mobile device, for some reason.
Any ideas?
Separate the issue of which fields to publish from which users you want to publish data on.
Presumably you want to show avatars for other users that the current user is interacting with. You need to decide what query to use in
Meteor.users.find(query,{fields: {...}});
so that you narrow down the list from all users to just pertinent ones.
In my app I end up using reywood:publish-composite to publish the users that are related to the current user via an intermediate collection.
The unscalability of utilities:avatar seems, as far as I can tell, to be a real issue, and there isn't much to be done about it except to remove utilities:avatar and rewrite the avatar URL-fetching code by hand.
As for the avatars not appearing on mobile devices, the answer was simply that we needed to grant permission to access remote URLs in mobile-config.js, like this:
App.accessRule("http://*");
App.accessRule("https://*");
I am using Meteor 4.2 (Windows) and I am always getting the "update failed: 403 -- Access denied. Can't replace document in restricted collection" when I am trying to update an object in my collection. Strangely I had no problem inserting new ones, only updates are failing.
I tried to "allow" everything on my collection:
Maps.allow({
insert: function () { return true; },
update: function () { return true; },
remove: function () { return true; },
fetch: function () { return true; }
});
But still, this update fails:
Maps.update({
_id: Session.get('current_map')
}, {
name: $('#newMapName').val()
});
Is there something else I can check? Or maybe my code is wrong? Last time I played with my project was with a previous version of Meteor (< 4.0).
Thanks for your help.
PS: Just for information, when I do this update, the local collection is updated, I can see the changes in the UI. Then very quickly it is reverted along with the error message, as the changes has been rejected by the server-side.
Alright, the syntax was actually incorrect. I don't understand really why as it was working well before, but anyway, here is the code that works fine:
Maps.update({
Session.get('current_map')
}, {
$set: {
name: $('#newMapName').val()
}
});
It seems like it must be related to what you're storing in the 'current_map' session variable. If it's a db object, then it probably looks like {_id:<mongo id here>} which would make the update finder work properly.
I ran into the same issues, and found the following to work
Blocks.update {_id:block_id}, {$set: params}
where params is a hash of all the bits i'd like to update and block_id is the mongo object id of the Block i'm trying to update.
Your note about the client side update (which flashes the update and then reverts) is expected behavior. If you check out their docs under the Data and Security section:
Meteor has a cute trick, though. When a client issues a write to the server, it also updates its local cache immediately, without waiting for the server's response. This means the screen will redraw right away. If the server accepted the update — what ought to happen most of the time in a properly behaving client — then the client got a jump on the change and didn't have to wait for the round trip to update its own screen. If the server rejects the change, Meteor patches up the client's cache with the server's result.