Make a wirecloud query using NGSI API - fiware-orion

I'm trying to make a query using NGSI API in my Wire Cloud widget but always fails and I don't receive anything:
var descubrimiento = connection.query([{
isPattern: true,
id: MashupPlatform.prefs.get('idfuente')
}],
null,
{
flat: true
}
);
connection is the object where I have the connection with the context broker and it works fine. Also if I make the query with the NGSI10 RESTful API via RESTclient I receive the data that I want but with the wirecloud NGSI API in my widget it is imposible to make the query.
Someone has this problem too?

Take a look at this tutorial about how to use the Orion Context Broker from WireCloud.
The main problem is that you're assuming the method the query response is returned synchronously while in reality is returned asynchronously. For being able to read the returned data, you need to pass a onSuccess callback. This callback will be called as soon the response from the Orion server is available. The data returned by Orion will be passed as the first parameter of the onSuccess callback function (see the referenced documentation for examples about how the returned data is formatted). E.g:
connection.query([{
isPattern: true,
id: MashupPlatform.prefs.get('idfuente')
}],
null,
{
flat: true,
onSuccess: function (descubrimiento) {
...
}
}
);

Related

How is GraphQL more efficient than REST?

Let's take the SpaceX launches api for example.
If I make a request with REST (in Node.js)
It'll look something like this :
router.get('https://api.spacexdata.com/v3/launches', function (req, res) {
// What to do with it
})
This will get me all launches data.
Now, with GraphQL you specify only the fields you want.
const LaunchType = new GraphQLObjectType({
name: 'Launch',
fields: () => ({
flight_number: { type: GraphQLInt },
mission_name: { type: GraphQLString },
launch_year: { type: GraphQLString },
launch_date_local: { type: GraphQLString },
launch_success: { type: GraphQLBoolean },
rocket: { type: RocketType }
})
})
But.. in the query you supply the same route as the REST version route.
resolve(parent, args) {
return axios
.get('https://api.spacexdata.com/v3/launches')
.then((res) => res.data)
}
So how is the GraphQL request different? doesn't it actually fetch the whole data too?
Can it "traverse" the route somehow when it makes the request?
In your example, the server does in fact fetch the whole response from the underlying REST API. Your resolve function is just the function that's called to get the value of a particular field. Whether you call axios.get inside a resolver or outside of one doesn't matter -- it's still going to return the same thing.
However, any client making a request to your GraphQL service will have to specify which fields (flight_number, mission_name, etc.) it wants returned. When the client makes the request, the GraphQL service calls the REST API, gets the full response and then transforms it to reflect the fields requested by the client.
Whether this is more efficient than calling the REST endpoint directly depends on a lot of factors. By only returning the requested fields, a GraphQL response payload may be smaller compared to the "complete" response returned by the REST endpoint. However, GraphQL does add overhead, and having any kind of proxy between your client and the REST API will add latency as well -- that may or may not be offset by any gains from the smaller payload. That said, if you cache the responses from the REST endpoint on your server, you can speed things up quite a bit.

node.js authentication with sequelize and passport - promise and callback confusion

Hopefully someone can help me solve what I am sure is a rookie mistake.
I am trying to adapt an authentication app originally based on mongodb, to work with sequelize\MSSQL instead, but getting tied up in knots with trying to blend a callback-based working example with
seqeulize's promised based approach.
Both MongoDb\Sequelize offer a findOne() method.
Original (working) code referencing MongoDb collection:
module.exports.getUserByUsername = function(username,callback){
var query = {username: username};
User.findOne(query,callback);
}
The callback in this case is from a separate calling module and is the standard verify password of passport.js's local-strategy.
Since the sequelize findOne() method expects a where clause I had hoped the following would be an out of the box solution:
module.exports.getUserByUsername = function(username,callback){
var query = {where: {username: username}};
User.findOne(query,callback);
}
This outputs a functional query into the console.log, but the callback doesn't fire, so the page hangs.
Looking at the respective API docs it appears that sequelize findOne() is exclusively promise based whereas MongoDb findOne() returns a promise only if where a callback function is not passed to the findOne() method, otherwise flow is handed to the callback when one is provided as is the case with the working example.
I tried the following adaptation to work with a sequelize promise (and quite a number of permutations thereof calling the callback function within the .then() clause etc)., but all fail with a hanging page: :
module.exports.getUserByUsername = function(username,callback){
var query = {where: {username: username}};
return User.findOne(query).then(user => {
console.log(user.get({ plain: true }));
return user.dataValues;
//callback(user.dataValues)
}).finally(() => {
console.log('done!')
});
}
The console.log(user.get()) spools out the correct details showing the database query executed correctly returning the required user data, so I feel that I'm very near to finding the right syntax to delivering this back to the passport callback.
Any help would be much appreciated!
Add raw property to true like this, and you can get the user object
User.findOne({ where : {username:username}, raw: true}).then( user => {
return user
})

Using sails.io pubsub works with shortcuts, but not with RESTful record creation

I'm having an issue where I'm getting events from the sails resourceful pubsub when I create a record with the shortcut routes, but not with the RESTful routes.
In my client code, I have a sails socket that I listen to for the model:
io.socket.on('users', function(event){console.log(event);})
If I use a shortcut route to create a record (http://localhost:1337/users/create?name=test), I get the callback in the console as expected:
>{verb: "created", data: {…}, id: 44}
However, if I use the socket to post from the client, the callback never fires.
io.socket.post('/users', { name: 'test' });
The record is created in the DB, and even more confusing is that the Sails server log says its publishing the message:
silly: Published message to sails_model_create_users : { verb: 'created',
data:
{ name: 'test',
createdAt: '2017-10-09T02:58:18.218Z',
updatedAt: '2017-10-09T02:58:18.218Z',
id: 44 },
id: 44 }
I'm the using generic blueprints, sails is v0.12.14. Any ideas what I'm doing wrong?
I figured out why I wasn't getting the events back on the pubsub. Sails excludes the socket that sent the req from the event. You can get the result from the post callback, but this breaks my nice dataflow. So I ended up using io.sails.connect() to create 2 sockets, one for the crud calls and one for the pubsib.

Sails pubsub how to subscribe to a model instance?

I am struggling to receive pubsub events in my client. The client store (reflux) gets the data from a project using its id. As I understand it this automatically subscribes the Sails socket for realtime events (from version 0.10), but I don't see it happening.
Here's my client store getting data from sails
(this is ES6 syntax)
onLoadProject(id) {
var url = '/api/projects/' + id;
io.socket.get(url, (p, jwres) => {
console.log('loaded project', id);
this.project = p;
this.trigger(p);
});
io.socket.on("project", function(event){
console.log('realtime event', event);
});
},
Then I created a test "touch" action in my project controller, just to have the modifiedAt field updated.
touch: function(req, res){
var id = req.param('id');
Project.findOne(id)
.then(function(project) {
if (!project) throw new Error('No project with id ' + id);
return Project.update({id: id}, {touched: project.touched+1});
})
.then(function(){
// this should not be required right?
return Project.publishUpdate(id);
})
.done(function() {
sails.log('touched ok');
res.ok();
}, function(e) {
sails.log("touch failed", e.message, e.stack);
res.serverError(e.message);
});
}
This doesn't trigger any realtime event in my client code. I also added a manual Project.publishUpdate(), but this shouldn't be required right?
What am I missing?
-------- edit ----------
There was a complication a result of my model touched attribute, since I set it to 'number' instead of 'integer' and the ORM exception wasn't caught by the promise error handling without a catch() part. So the code above works, hurray! But the realtime events are received for every instance of Project.
So let me rephrase my question:
How can I subscribe the client socket to an instance instead of a model? I could check the id on the client side and retrieve the updated instance data but that seems inefficient since every client receives a notification about every project even though they only should care about a single one.
----- edit again ------
So nevermind. The reason I was getting updates from every instance is simply because at the start of my application I triggered a findAll to get a list of available projects. As a result my socket got subscribed for all of them. The workaround would be to either initiate that call via plain http instead of a socket, or use a separate controller action for retrieving the list (therefor bypassing the blueprint route). I picked the second option because in my case it's silly to fetch all project data prior to picking one.
So to answer my own question. The reason I was getting updates from every instance is simply because at the start of my application I triggered a findAll to get a list of available projects. As a result my socket got subscribed for all of them.
The workaround would be to either initiate that call via plain http instead of a socket, or use a separate controller action for retrieving the list (therefor bypassing the blueprint route). I picked the second option because in my case it's silly to fetch all resources data prior to selecting one.
Here's the function I used to list all resources, where I filter part of the data which is not relevant for browsing the list initially.
list: function(req, res) {
Project.find()
.then(function(projects) {
var keys = [
'id',
'name',
'createdAt',
'updatedAt',
'author',
'description',
];
return projects.map(function(project){
return _.pick(project, keys);
});
})
.catch(function (e){
res.serverError(e.message);
})
.done(function(list){
res.json(list);
}, function(e) {
res.serverError(e.message);
});
},
Note that when the user loads a resource (project in my case) and then switches to another resource, the client is will be subscribed to both resources. I believe it requires a request to an action where you unsubscribe the socket explicitly to prevent this. In my case this isn't such a problem, but I plan to solve that later.
I hope this is helpful to someone.

Ember Data not storing ID

I'm working on a website using nodejs for server side, emberjs for client side and mongodb for database. I have a page where a user profile is created and saved but the id of the data is stored as undefined unless I refresh. Is there a way atound this?
I would have to see the specific code in order to answer this with certain, but I suspect that you're either not waiting for a response from the server, or you're not passing in the model when you transition to the new route. Ember-data automatically updates when it gets a response from the server.
The general flow should go like this:
Send your post request to the server.
The server creates the user in Mongodb, and when it gets that object back, it sends it back to the client.
On the client, you wait to get the user back from the server, and pass the model into your transitionTo helper.
Here's an example on the Ember side:
App.UserCreateController = Ember.ObjectController.extend({
actions: {
createUser: function() {
var self = this;
this.get('model')
.save()
.then(function() {
self.transitionToRoute('profile', self.get('model'));
}, function() {
alert('User not successfully saved');
});
}
}
});
Another possible issue is that you're not sending the data back as Ember-data expects. i.e. Your payload should look something like this:
{
user: {
_id: 'lkj234l23jlk5j4l32j5lk34',
name: 'Jon Snow'
}
}
And you should let Ember know that it should be using the _id instead:
App.ApplicationSerializer = DS.RESTSerializer.extend({
primaryKey: "_id"
});
If this isn't your problem, post some code or give more details.