How to subscribe and listen to channels with feathers client? - feathersjs

Please point me on the right path. I use angular for the client and I get my data with:
private getOrders(query: {}) {
return from(this._feathers.service('orders').find({ query }));
}
this works great and I get an observable in return.
But I don't know how to get the messages on the client side.
For instance, the app template in channels.ts mentions something like this:
app.service('messages').publish(() => {
return [
app.channel(`userIds/${data.createdBy}`),
app.channel(`emails/${data.recipientEmail}`)
];
});
Well, how can I get the data from the client for emails/${data.recipientEmail}?
What is the syntax?

Things are actually pretty straight forward!
My confusion was that I had experience with socket.io and I created a channel per each service I had back then.
In feathers, the channels are a means of sending the data. So every service can post to any channel and it all depends to which channel you subscribe to!
On the client side I had the confusion of how I can access that data thinking that I need a 'custom' channel name and method. This actually does not matter as the clients are subscribed to different channels and in the end data does come from a service and method in that service!
I hope this makes sense and clears up confusion for people that are like me. :)
This article clears things up: https://blog.feathersjs.com/feathersjs-channel-subscriptions-647c771ca6c8

Related

Postman interceptor request running forever

I am trying to intercept a website - https://www.kroger.com/pl/chicken/05002. In the chrome network tab, I see the request as below, with the details of the products nicely listed as JSON
I copied the cURL as bash and imported it as raw text in Postman. It ran forever without any response. Then I used the intercept feature and still it is running forever.
When both the requests are exactly same, why is it running in Chrome and not in Postman? What am i missing? Any help is appreciated, thanks in advance.
This is probably happening because they don't want you to do what you are trying to do. Note the "filter.verified" param in the URL.
You may want to try reaching out to them for an external API token - especially if you are creating an app or extension to compare competitive prices with the intention of distributing said app or extension - regardless of if it is for financial compensation or not.
Ethically questionable workaround (which would defintely need to be improved upon - this is simply an example of how you could solve your problem...):
GET https://www.kroger.com/search?query=chicken&searchType=default_search&fulfillment=all
const html = cheerio(responseBody);
var results = [];
html.find('div[class="AutoGrid-cell min-w-0"] > div').each(function (i, e)
{
results.push({
"Item": e.children[e.children.length-3].children[0].children[0].children[0]["data"],
"Price": e.children[e.children.length-4].children[0].attribs["value"]
})
});
console.log(results);
If you are unable to obtain an API token from them, this would probably be a legal way to accomplish what you want.

In angular 2+ (Component => Service A => ServiceB), need help to understand the flow

In angular 2+, I have a component A which calls service A where i make some changes and call service B (Http Calls) and get the data which is simply passed back to service A, now i need to subscribe into service A to see the data and also subscribe into Component A to display data there?
why i need to subscribe at 2 places which means its making the http calls twice (which is not good at all)
what is the best way where I can fetch and store data in Service A by subscribing and do all manipulation and simply send that object back to component A to display it? even I try to make a variable in subscribing section in service A but when I try to log that variable outside the subscribe block. it is undefined.
thanks for the help.
while searching for the answer, I found one way (or can called worked around) that is to use "async-await" feature in angular with HttpClient.
which will basically wait at the same line of execution till you get result (success or error). and then proceed further with next line of execution.
for example:
async myFunction() {
this.myResult = await this.httpClient.get(this.url).toPromise();
console.log('No issues, it will wait till myResult is populated.');
}
Explanation:
adding async in front of the function to let it know that execution need to wait and the desire place (mostly at http service call as I need to wait till I get the result) we put await. so execution will go under wait period till it get the response back. and later. simply return the variable.

Global Feathers hooks and event filters

In Express, it's very easy to block access to all routes starting, say, with the /admin prefix, simply by adding a middleware to that path before adding handlers for any specific endpoints under that path.
In Feathers, it looks like we have to create some common hook modules and add them to every service we created, individually. Same goes for event filters.
I find the thought of forgetting to add an authentication hook or event filter scary, because I wouldn't notice the mistake unless I reviewed all service initialization code or got hacked. In that sense, an Express middleware with some sort of white-listing I can easily implement for exceptional endpoints gives me much more peace of mind.
Is it possible to do something like that in Feathers?
(P.S.: I just noticed I had protected my app's REST API, but had forgotten to protect all real-time events).
As of v1.6.0 feathers-hooks supports application hooks that run on all services via app.hooks:
app.hooks({
before(hook) {
console.log('Global before hook');
},
after(hook) {
console.log('Global after hook');
},
error(hook) {
console.error(`Error in ${hook.path} method ${hook.method}`, hook.error.stack);
}
});
For more examples see this blog post about error and application hooks.
As for the real-time events, channels are used which provide a safe way to send events only to the clients that should see them.

Create an API directly from a data source

I need to create my own REST API.
I just saw strongloop and loopback and I thought it will be perfect for my project.
In fact, I was able to get mysql connected using strongloop. However, I had to create something called a "model" and I did it. But, it was like creating a new model from scratch and use it for persisting on the Datasource.
Instead, what I was looking for, is to get a REST API directly from my model on the DB.
I mean taking the models from each table on the DB and then set them up as web services.
Is that possible?
I am newbie on these technologies, although I think it is an interesting question.
Thanks
I'm not sure of a Node tool to do what you're asking, but in other languages / databases you have some choices!
The only one I'm really familiar with is postgrest.
postgrest: You import your data into a Postgres database (similar to MySQL), and it generates a REST API on top of your tables instantly. Bam. Done. I've used this and it was amazingly awesome. You can also deploy it directly on Heroku.
StrongLoop actually has a "discovery" tool for just this purpose! Read up on that page, but here's the basic code to do it. Just drop this code in a file inside /server/boot/ (the docs are wrong on that, it must be in the directory I mention). Of course, you'll need to tailor it for your use case:
var loopback = require('loopback');
var ds = loopback.createDataSource('mysql', {
"host": "yourhost",
"port": 1234,
"database": "foobar",
"username": "someuser",
"password": "somepass"
});
// Discover and build models from a given table
ds.discoverAndBuildModels('PERSON', {visited: {}, associations: true},
function (err, models) {
// Now we have a list of models keyed by the model name
// You only need the rest of this if wanted to inspect what came in...
// For example, you could find the first record from the table
// and verify info or something.
models.Person.findOne({}, function (err, person) {
if(err) {
// handle this if need be...
console.error(err);
return;
}
// Some code using `person`
});
});
Good luck!
I was supposing "discovery tool" was to find out pattern, cluster or whatever else thing into the data. But following
the recomendation of #jakarella I went with more depth.
It was even easier than that, because you can do everything via StrongLoop Arc (GUI). I always prefer cli
but to have a general look of it, sometimes is better to start with the GUI if you don't have too much idea about the subject.
Anyway,
first of all you would need to connect your datasource before (installing previously the driver).
After that, through StrongLoop Arc you can do "discover the models" choosing your tables (taking care of run Arc and restarting every time
you get a new model) and that's it, you get an API over your Datasource
(for testing go to the explorer).
I described before generally the main tasks but if anyone needs more detail pls let me know. Hope this helps to anyone else who is looking to do
something similar
thanks guys for the interest.

node js + mysql push notification

I am working on project where I want to give notification like facebook. i.e. when someone comments on others profile or like any link on others profile. I want to use nodejs for real time push notification.
These data of comments, likes are stored in the mysql database in "Notification table" via ajax request or by posting the form to php.I found many tutorials of nodejs on net for the real time push notifications but unfortunately they talk about keeping watch on file and emits the notification when file is updated.
does anybody knows how to keep watch on the mysql table, so whenever, any data is inserted in the table, it emits the notification. I am not getting any way what kind of code I should write in nodejs.
Please let me know if more explanation is needed.
Thanks in advance.
You can use node.js with a mysql library to poll your database for new notifications, which I think is what you're trying to do. I've never done that specific task personally, but I know it's achievable.
In terms of what kind of code you need to write, try looking up "Node Middleware Tutorials" with perhaps some variations that include MySQL in the search query and you'll find at least an idea of what you should be looking for.
If I can I will update this answer with more specific code samples to get you moving in the right direction.
You can use nowjs and add on the after save (if you are using an mysql active record) to notify the client with this package.
On the server
var httpServer = require('http').createServer(function(req, response){ /* Serve your static files */ })
httpServer.listen(8080);
var nowjs = require("now");
var everyone = nowjs.initialize(httpServer);
everyone.now.logStuff = function(msg){
console.log(msg);
}
On the client
<script type="text/javascript" src="http://localhost:8080/nowjs/now.js"></script>
<script type="text/javascript">
now.ready(function(){
// "Hello World!" will print on server
now.logStuff("Hello World!");
});
</script>
For more information take a look at the examples