Error: Unrecognized operator: $nearSphere in meteor js - meteor

i have simple code in meteor js for find near by garages within 10 Kilometres the query works fine in my mongodb database if run it manually in robomongo it works fine but when i run it in my routes it throws an error. like this.
Error: Unrecognized operator: $nearSphere in meteor jsi
i see some blogs they said you need to call a server side method for this. so i use below code to call a server side route.
Router.route('/search/:name',
{name:'searchlist',
data:function(){
var searchedParams = this.params.name.split('-');
var lat = searchedParams.pop();
var lng = searchedParams.pop(1);
return {searchValue: Centers.find({ coordinates: { $nearSphere: { $geometry: { type: "Point", coordinates: [lng,lat] }, $maxDistance: 10000 } } })}
}
}, { where: "server" }
);
if anyone have idea please help.

You're mixing definitions for client and server side routes.
Server-side route should look like this:
Router.route('/search/:name', function(...){...}, { where: 'server' });
Client-side route could look like this:
Router.route('/search/:name, { ... });
Thus, your route is actually client-side route and minimongo doesn't have support for $nearSphere operator as noted here: https://github.com/meteor/meteor/blob/devel/packages/minimongo/NOTES

First, look at Styx answer and make the route a client route by eliminating this part:
', { where: "server" }'
Now that the router is available to the client, let's fix the $nearSphere issue, by changing the operator to $near. Use the following code:
Centers.find(
{
geoloc: {
$near: {
$geometry: {
type: "Point",
coordinates: [lng, lat]
}
}
}
}
);
Give it a try and let me know if it works.

Related

How to pass route param while using Inertia manual visit

How can I pass the route param while using Inertia manual visit, for example:
Route:
Route::post('/explore/gallery/like/{$post}', [ExploreController::class, 'likeToggle'])
->name('explore.post.like');
Component:
Inertia.visit(route('explore.post.like'),
{
method: 'post',
preserveScroll: true,
data: {
$post: this.id
},
},
);
but is shows the error tho,
Error occur in Ziggy, and says you need pass $post,
Ok, Change route('explore.post.like') to route('explore.post.like', this.id)
According Ziggy documentation you can also use like :
route('explore.post.like', this.id)
route('explore.post.like', [this.id])
route('explore.post.like', { $post: this.id })
A simple solution would be:
Inertia.post(route('explore.post.like', [this.id, 'if you have other params']), {}, {
preserveScroll: true,
});
Pls make sure the order is correct, follow the order of your route's param

AppSync BatchDeleteItem not executes properly

I'm working on a React Native application with AppSync, and following is my schema to the problem:
type JoineeDeletedConnection {
items: [Joinee]
nextToken: String
}
type Mutation {
deleteJoinee(ids: [ID!]): [Joinee]
}
In 'request mapping template' to resolver to deleteJoinee, I have following (following the tutorial from https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-dynamodb-batch.html):
#set($ids = [])
#foreach($id in ${ctx.args.ids})
#set($map = {})
$util.qr($map.put("id", $util.dynamodb.toString($id)))
$util.qr($ids.add($map))
#end
{
"version" : "2018-05-29",
"operation" : "BatchDeleteItem",
"tables" : {
"JoineesTable": $util.toJson($ids)
}
}
..and in 'response mapping template' to the resolver,
$util.toJson($ctx.result.data.JoineesTable)
The problem is, when I ran the query, I got empty result and nothing deleted to database as well:
// calling the query
mutation DeleteJoinee {
deleteJoinee(ids: ["xxxx", "xxxx"])
{
id
}
}
// returns
{
"data": {
"deleteJoinee": [
null
]
}
}
I finally able to solve this puzzle, thanks to the answer mentioned here to point me to some direction.
Although, I noticed that JoineesTable does have trusted entity/role to the IAM 'Roles' section, yet it wasn't working for some reason. Looking into this more, I noticed that the existing policy had following actions as default:
"Action": [
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:UpdateItem"
]
Once I added following two more actions to the list, things have started working:
"dynamodb:BatchWriteItem",
"dynamodb:BatchGetItem"
Thanks to #Vasileios Lekakis and #Ionut Trestian on this appSync quest )

angular 2 - asynchrone issue

I have a very simple Typescript script (ionic2 and angular2) that add an authentication header before an HTTP call. Here is the idea (simplified code):
function CreateAuthorization(){
this.header.append('tests' : 'test')
Storage.retrieve('Auth').then(data){
this.header.append('authorization' : data.token)
}
}
function customHttp(url){
CreateAuthorization();
Http.get(url, this.header);
}
In my Request header, I have 'test' = 'test' but I do NOT have 'authorization' = 'MyToken'.
How can I make in sort to "wait" for the header to be set in Storage.retrieve('Auth') ?
I know that I can use a setTimeout() but I don't like this dirty workaround.
The solution could be an observable/promise but I don't really master those things.
Any help would be very appreciated :)
Geoffrey
It's because your CreateAuthorization method is asynchronous. I would try something like that leveraging promise chaining to be notified when the Authorization header is actually added:
createAuthorization() {
this.header.append('tests' : 'test');
return Storage.retrieve('Auth').then(data){
this.header.append('authorization', data.token);
return true;
}
}
customHttp(url) {
this.createAuthorization().then(() => {
this.http.get(url, { headers: this.header });
});
}

Proper way to .findOne() in Iron:router

Why is it that .findOne() does not work when executed inside the Router?
It always returns undefined.
Yet .find() works without any problems. Also tested .findOne() by manually entering the condition and the ._id manually.
Is .findOne() not designed to work inside the Router?
It's working properly in my application. I implemented it like this:
Router.map(function() {
this.route('training', {
path: '/training/:id',
data: function() {
return Trainings.findOne({id: this.params.id});
},
notFoundTemplate: 'notFound',
title: "Training"
});
});
it works fine!
maybe you're trying to pass the result to an iterator? it's not a cursor.
try a find().fetch() and use the result in the same way.
if it's a data/timing issue you could also guard with a ready() function.
you don't need to if you're using it reactively but this gives you a bit more explicit knowhow when things happen, yet without using a waitOn.
in coffeescript:
#---------routes ---------
#route 'routeName',
path: '/path/to/:cname'
onBeforeAction: ->
Meteor.subscribe('Things', {
cname: #params.cname
})
this.next()
data: ->
if #ready()
data = {
params: #params
}
data.lesson = Things.findOne({cname: #params.cname})
return data

Meteor/Iron-Router: how to define routes using data from settings.json

For the URL to which a route applies I have a part defined in settings.json, like this
baseUrl: '/private'
My settings are published and accessible through the collections 'Settings' (on the client). So I tried the following:
Meteor.subscribe('settings');
Deps.autorun(function () {
var settings = Settings.findOne():
if (settings) {
Router.map(function () {
this.route('project', {
path: settings.baseUrl + '/:projectId,
controller: 'ProjectController'
});
});
}
});
The problem is that during initialisation the data is not yet on the client available, so I have to wait until the data is present. So far this approach doesn't work (yet). But before spending many hours I was wondering if someone has done this before or can tell me if this is the right approach ?
Updated answer:
I published solution in repository : https://github.com/parhelium/meteor-so-inject-data-to-html
. Test it by opening url : localhost:3000/test
In this case FastRender package is useless as it injects collection data in the end of head tag -> line 63.
Inject-Initial package injects data in the beginning of head tag -> line 106.
Needed packages:
mrt add iron-router
mrt add inject-initial
Source code:
Settings = new Meteor.Collection("settings");
if (Meteor.isClient) {
var settings = Injected.obj('settings');
console.log(settings);
Router.map(function () {
this.route('postShow', {
path: '/'+settings.path,
action: function () {
console.log("dynamic route !");
}
});
});
}
if (Meteor.isServer){
if(Settings.find().count() == 0){
Settings.insert({path:"test",data:"null"});
}
Inject.obj('settings', Settings.findOne());
}
Read about security in the bottom of the page : https://github.com/gadicc/meteor-inject-initial/
OLD ANSWER :
Below solution won't work in this specific case as FastRender injects data in the end of head tag. Because of that Routes are being initialized before injected data is present.
It will work when data from Settings collection will be sent together with html.
You can do that using package FastRender.
Create file server/router.js :
FastRender.onAllRoutes(function(path) {
// don't subscribe if client is downloading resources
if(/(css|js|html|map)/.test(path)) {
return;
}
this.subscribe('settings');
});
Create also publish function:
Meteor.publish('settings', function () {
return Settings.find({});
});
The above code means that if user open any url of your app then client will subscribe to "settings" publication and data will be injected on the server into html and available for client immediately.
I use this approach to be able to connect many different domains to meteor app and accordingly sent proper data.

Resources