Synchronize MeteorJS promise based migration - meteor

The notification always appears "Migrations: Finished migrating." before the real migration seed is finished. I chained all. I've checked all.
During migration, we use the async mechanism.
const { db } = MongoInternals.defaultRemoteCollectionDriver().mongo;
I've just found that MeteorMigration does not support promise-based functional. As a solution we use Meteor.wrapAsync. But it does not help.
const wrapIntoMongoTransaction = Meteor.wrapAsync(function (func, callback) {
wrapIntoMongoTransactionAsync(func).then(callback);
});
And then simply call.

Promise.await from the package meteor/promise does it well. It makes asynchronous to synchronous code.
My code becomes looking the following way:
import { Promise } from 'meteor/promise';
function wrapIntoMongoTransaction(func) {
Promise.await(wrapIntoMongoTransactionAsync(func));
}

Related

Nuxt 3 HTTP request on demand after rendering: a client-side fetch

Nuxt 3 has those amazing data fetching functions (ex.: useFetch), but I come out on a situation that I need to make request after the rendering time (ex.: calling from a button and send a search term).
As I far know, useFetch are not working on client-side, here is what I have trying to do
<template>
<button #click="goSearch()">Search</button>
</template>
setup() {
const goSearch = async () => {
const { data } = await useFetch('search', () => $fetch('/api/search'));
console.log(data.value);
};
return { goSearch };
},
}
Does nuxt3 offers a built in function to make http request on demand (client-side official http axios like)?
$fetch should work. The problem were a small bug that is now fixed. If you are experiencing this bug, just upgrade nuxt/ohmyfetch lib
npx nuxi upgrade --force
More here:
https://github.com/nuxt/framework/issues/2502#issuecomment-999783226
useFetch is the same as using $fetch, here why not simply use fetch already in your code ?
const { data } = await $fetch('/api/search' );
i think you code is simply no just youcan use useFetch even on client side but like that :
const { data } = await useFetch('/api/search')

Is it possible to stub meteor methods and publications in cypress tests?

Is it possible to stub meteor methods and publications in cypress tests?
In the docs (https://docs.cypress.io/guides/getting-started/testing-your-app#Stubbing-the-server) it says:
This means that instead of resetting the database, or seeding it with
the state we want, you can force the server to respond with whatever
you want it to. (...) and even test all of the edge cases, without needing a server.
But I do not find more details about that. All I can find is, that when not using the virtual user in the tests to fill the database, it is possible to call API calls on the app, like so:
cy.request('POST', '/test/seed/user', { username: 'jane.lane' })
.its('body')
.as('currentUser')
In my opinion that is not a "stub". It is a method to "seed" the database.
Is it possible to tell cypress to answer a meteor method in the client code like
Meteor.call('getUser', { username: 'jane.lane' }, callbackFunction);
with some data, it would give back in production?
I can only show an example using sinon to stub Meteor method calls:
const stub = sinon.stub(Meteor, 'call')
stub.callsFake(function (name, obj, callback) {
if (name === 'getUser' && obj.username === 'jane.lane') {
setTimeout(function () {
callback(/* your fake data here */)
})
}
})
That would be of corse a client-side stub. You could also simply override your Meteor method for this one test.

Redux Offline debounce server requests

I'm trying to work out the best way to get Redux Offline to debounce server requests.
Currently when the server is busy, it saves them up in a queue and sends all of them. I'd like it just to save the last one but use the same Save action to update the redux store.
My code in the action is:
export class SaveSession extends OfflineAction<SessionTypes> {
public readonly type = SessionTypes.SAVE_SESSION;
constructor(public session: ISession) {
super();
this.meta = {
offline: {
effect: {
url: `${process.env.REACT_APP_API}/api/session/save`,
body: JSON.stringify(session),
method: 'POST',
headers: authHeader()
},
commit: new SaveSessionSuccess(),
rollback: new SaveSessionError()
}
};
}
}
I'm looking through the documentation but I can't see anything around debouncing server requests.
Is this possible?
Have a look at this link from the documentation.
It seems like you will be interested in overriding the enqueue function to adjust the logic to suit your need: some kind of smart queue.
They said they've come up with smart-queue to serve this purpose: check this. Check it out and roll out the mechanism to match your requirement.

Are there 'private' server methods in Meteor?

Is there a way to stop a Client calling a Server Method from the browser console?
I gather from the Unofficial Meteor FAQ that there isn't. I just wanted to check if that's definitely the case - the FAQ isn't really specific. I mean are there no 'private' methods?
In meteor the 'methods' described by Meteor.methods can all be called from the client. In this sense there aren't private methods because the purpose of the RPC call is for the client to make the call.
If you want a 'private' method you could use an ordinary JavaScript method. If you define the method with var, it would only be accessible within the file, and cannot be called from the client.
var yourmethod = function() {
...
}
which is equivalent to:
function yourmethod() {
...
}
Or you can define it so any of your server script can use it:
yourmethod = function() {
....
}
If you mean you want a RPC method call that is accessible only from the javascript code, but not from the javascript console in chrome this isn't possible. This is because the idea behind meteor is all RPCs from the client are not trusted & there is no way to distinguish whether it came from the console or not. You can use meteor user authentication or Collection.allow or Collection.deny methods to prevent any unauthorized changes this way.
I made a private method by checking this.connection to be null.
Ref: http://docs.meteor.com/#/full/method_connection
Ex.
Meteor.methods({
'serverCallOnlyFunc': function() {
if (this.connection === null) {
//do something
} else {
throw(new Meteor.Error(500, 'Permission denied!'));
}
}
});

How to call async method from Meteor own callbacks?

I've just spent a few hours reading SO with answers such as Meteor: Calling an asynchronous function inside a Meteor.method and returning the result
Unfortunately, I still didn't manage to user fibers, or futures for that matter.
I'm trying to do something fairly simple (I think!).
When creating a user, add a variable to the user object, based on the result of an asynchronous method. So imagine if you will my async method is called on a 3rd party db server called BANK, which could take several seconds to return.
Accounts.onCreateUser(function(options,user){
var Fiber = Npm.require("fibers");
Fiber(function() {
BANK.getBalance(function(err, theBalance) {
if (err) return console.log(err);
_.extend(user,{
balance: theBalance;
});
});
}).run();
return user;
});
So what happens in the above is that the BANK method is called, but by the time it returns the code has already moved on and _.extend is never invoked.
I tried placing the return call inside the Fiber, that only made things worse: it never return user. Well it did, but 3 seconds too late so by then everything downstream was bailing out.
Thank you for any help!
Answering my own question which hopefully will help some people in the future. This is based on the excellent advice of Avital Oliver and David Glasser to have a look at Mike Bannister's meteor-async.md. You can read it here: https://gist.github.com/possibilities/3443021
Accounts.onCreateUser(function(options,user){
_.extend(user,{
balance: getBalance(),
});
return user;
});
function getBalance() {
var Future = Npm.require("fibers/future");
var fut = new Future();
BANK.getBalance(function(err, bal) {
if (err) return console.log(err);
fut.return(bal);
});
return fut.wait();
}
I believe there's an even better way to handle this, which is directly by wrapping the BANK API in Futures within the npm package itself, as per this example (from Avital Oliver): https://github.com/avital/meteor-xml2js-npm-demo/blob/master/xml2js-demo.js
I hope it helps!
Use this.unblock() on server side code.
From Meteor 1.0 documentation: "Allow subsequent method from this client to begin running in a new fiber.On the server, methods from a given client run one at a time. The N+1th invocation from a client won't start until the Nth invocation returns. However, you can change this by calling this.unblock. This will allow the N+1th invocation to start running in a new fiber."
Meteor.methods({checkTwitter: function (userId) {
check(userId, String);
this.unblock();
try {
var result = HTTP.call("GET", "http://api.twitter.com/xyz",
{params: {user: userId}});
return true;
} catch (e) {
// Got a network error, time-out or HTTP error in the 400 or 500 range.
return false;
}
}});
method calls use the sync style (see 'sync call' here http://docs.meteor.com/#meteor_call) on the server side, which is where this create user method runs - you should be able to do something like
Accounts.onCreateUser(function(options, user) {
user.balance = Meteor.call('getBankBalance', params);
return user;
});
Thanks yo so much that's work, This solution its better for Meteor projects, because Fibers module installed by default. mrt add npm has a method for this too -> Meteor.sync . For any nodeJS projects there is a other module based on Fibers, its name is Fibrous
Reference:https://github.com/goodeggs/fibrous

Resources