How To Create Your First Flow In Node-RED 🌦 | Node-RED Basics

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today i'm going to teach you the fundamentals of node-red and at the same time show you how to build a weather forecast dashboard to make the dashboard work we'll need to integrate with three online apis that will provide the current weather forecast a five-day forecast and information about the country connected to the town or city being searched this tutorial is an unscripted deep dive showing you step by step how we bring these apis together in node-red to produce a weather service in the form of a ui dashboard once you've gone through this video you'll have a good enough understanding of node rare to be able to get up and running with your own flows just a reminder that if you enjoy this video show some love by giving it a like and for more content like this be sure to subscribe to my youtube channel with all that being said let's dive right in right so we are live and unscripted i will try and keep everything as flowy as possible mind the pun so this is the weather dashboard that we are going to be creating and to start things off let's just focus on our interface and what do we need so here i have a node-red interface the node-red editor i'm currently using agility node red but any stock standard node-red install will work just fine because we are not going to be importing or using any third-party modules or anything special we're going to be using the out-of-box nodes inside node-red so if you haven't got node-red installed at this time then your two options right here is to go to node-red's documentation node.red.org click on documentation and click on getting started that will show you uh all kinds of different ways that you can install and set up node-red alternatively if you want to install node-red the way i do you can just go to my channel on youtube bleeding code and you'll see that there is a video of the advanced setup of node red in easy steps that will set up node red in the way that i have it right now in this video right so also before we start actually creating flows and adding nodes to the editor workspace over here let's first just go back and understand how did i get to the point where i created this no this weather dashboard well the first thing that i did was i said okay fine what i needed was to teach everyone the basics of node-red which is the purpose of this video but i had to do it in some sort of fun way so the first thing that i did was went online and checked what are the most popular online apis that people seem to want to use and in the top five for on many different sites open weather map and rest countries keep getting mentioned so i said okay fine that's pretty cool so let's use open weather map and get the current forecast let's maybe get the five-day forecast and let's use the country's apis to get information about the country uh that that's related to the search for the voters dashboard so when i'm searching janisberg over here the country is south africa so while i'm getting the current forecast the five-day forecast then i'm also getting information about south africa so i'm actually using three different online services well i'm using two online services but three apis in total so that's great once i had that information i moved forward and i said okay fine i need to start testing these apis so that i know what i'm going to get back so if we go to open weather map i use their online api services open weather map and you just sign up for a free account and you'll need to go and generate an api key under your profile and once you've done that you can go to the api docs and start understanding what kind of apis you can work with so we can see over here we've got the current weather data we've got an hourly forecast of four days we've got a couple of other extra apis over here the i know for a fact that the free version does not allow you to get the forecast for four days but the free version does allow you to get the current weather data and the daily forecast for 16 days so these are the two apis that i landed up using so once i knew what apis i wanted to use the next step was to test them in some sort of api testing tool of which i use a postman for my api testing and you can do the same it's a free app you can download it you don't even need to sign up it's postman.com download the app and it will look something like this the postman dashboard and you can see over here that i am now i tested the apis using over yes so i've got my three apis the first one was open with a map i needed to provide it's very simple yes the a yes the url in order to interface with open weather map you need your app id okay so i just created a dummy app id over here you need to and then that's all you really need then you need the search query and the search query can either be like a city or suburb or town but if you want to be more specific because there could be duplicate towns like for example florida can exist in the u.s and it can exist in south africa so what happens is if you're not specific then it will default and in this case it will bring through us so in the event that you need to you want to be specific then you can also just add a comma and the country code and then that will bring through a more specific town that you were doing a query for the optional item over here is units and by default i think it's fahrenheit but in south africa we use the metric system so i to actually provide the units query on top uh query param and specify that i want uh metric results and that would return the following so here's my json information and this is all kinds of data that i get related to my search query which was for chicago so which is fine because this is what i want this is the information that i'm going to be using so there's the temperature it feels like the pressure humidity all kinds of stuff that we can use in for our dashboard then we go to the 16 day api which is almost some it's almost the same it's got a little bit of a different url the query is exactly the same the app id is the same and again override the units if you don't want fahrenheit and that will then just return the next 16 days worth of data to you which provides more or less the same information that you had on the current day's weather forecast so that's good i mean we only want a five-day forecast but we're gonna we're gonna we're gonna filter and modify that information in node-red so that's fine finally what we also do is uh when we do these queries we actually get the country code so that's great because then i went to the rest countries api which is this website every year and you don't even have to sign up for this you can just start using the apis from their page so what i said okay fine because i've got the code i can be very specific when i want to return information about a country so i'll end up using this api of this year where i just provide the country code which i get from the open weather maps apis when i queried uh the weather forecast for the town so this is the information that i will get back from uh the rest countries api so that's cool that's how i collected uh and prepared myself in order to provide all the information that i want on the weather dashboard so there's my apis all ready to go so the second part was how did i create this dashboard because i wanted to really fly through with this demonstration and focus on node-red and less on designing user interfaces i really hacked this together using a couple of online tools and instead of building like a react app with a specific ui framework i just went and said okay fine let's use twitter bootstrap because they got a lot of great online resources so i went to bootsnip which is an online site that provides all kinds of twitter bootstrap snippets anything from dashboards to forms to to to anything that you can think of and i searched through a couple of these and i came up with these two pages over here so this one this is some sort of dashboard page and i said okay fine this looks good i'll just grab the html i grab the css from this and then i went through another search just to get some sort of header and search bar i thought okay that's cool i'll just grab the html and css from this and i put it together in an online tool called jsbin so i actually just sort of started throwing the html and everything inside yeah until i got to a point where i hacked everything and got a user interface that's still responsive i i can't think of how quicker one can actually bring together a user interface but for for things like this this is obviously not a full-fledged application then i go with react then i go with redux then i go with with a like and design which is what i usually use a good example well here we go so this is this is now full-fledged react application uh using and design and i will usually go that uh go with that for professional app for but for what we're doing if you just need like an internal report or something it's really great just to sometimes put together something quick and easy that will that will deliver what you need in the meantime and then you can expose this through node red which is exactly what i'm going to show everyone in in a very short while so here i put all the html and everything together so yes don't this is not about best practices html this is not about putting your css in one this is about teaching you the basics of node red so all i felt like i could should do for everyone is just show you how i got to the point where i knew what i wanted to build and i had already designed the user interface so he has the html that i'm going to be using so just a final scene while we are on the html there's only a little bit of logic at the bottom a little bit of jquery logic and all it's doing is it's got a click event it's listening for a a submit or a click event on this field over here so that when we hit enter it does at least say please provide a search term and once a search term is provided all it does is it grabs the current protocol the host and path name and it reloads it to include the search term that was provided that's all that's happening okay so there's no fancy javascript http requests or anything happening over here that's not the point of this tutorial all i'm doing is i'm saying okay fine let me reload the page and provide the search term and then the page can then load accordingly now the beauty about this is that all the business logic all the intelligence is actually going to sit in node-red we've kept our html page as dumb as possible and on purpose so this is very very cool now we finally get to node-red alright now we finally get to node-red so the first thing that we want to do is we'll say okay fine how can we expose this page this raw static page that i've created yeah how can we expose this through node-red as opposed to having to put it into some sort of node project or react project and have to deploy it to the cloud what can we do just to get it available via url so that we can start seeing this raw static page all right so i'm going to copy all this content over here and we are going to go to node red all right so here's my node red editor and through this exercise now i'm also going to teach you a few things about node-red remember the focus of this tutorial is to learn about node-red it's the learning the weather app is just a bonus okay so in order to expose this html via url so that people can access it we need an http node and we also need a special node called a template so that we can actually store the html that we put together so on our left hand side we've got the node palette over here and this is where all the available nodes for uh are in our node-red environment allowing us to create these flows okay so we can obviously uh sort of scroll down and up in order to see all the nodes that are available we can also collapse and expand the categories so all the nodes are sort of categorized as your common nodes here's your function nodes here's your network nodes and look at that there's our http in okay we'll drag that and for every request we need a response we're going to drag that as well so those are the two ways that you can sort of move nodes onto the workspace now i know for a fact that we need another node called a template node okay so instead of having to search for that because we might not know where it is let's go and actually do a little bit of a search on top so i'll say search template oh i see this too all right well which one do i use well that's easy just hover over the one and you'll get a nice pop-up that shows you what exactly it gets it's used for and we can see as part of a function node whereas this is specific it's an agility node called templates and it serves a very different purpose so hovering over them is how you can see what what this node can do for you so we've got our template node we want to use this and we will drag it to the workspace so these three nodes are going to give us everything we need to expose this static html page so how are we going to do that firstly we have to go and double click on this http in we are going to keep it as a get request and we just need to give it a url path so let's go forward slash weather forward slash dashboard uh weather dashboard endpoint the name gets used uh over here inside the workspace so that you can see what the node is actually doing for us so there we go we're the dashboard endpoint and over here we can just say html content and yeah is where i can paste all that html so don't worry too much about the syntax highlighting bin mustache we're going to get to that in a moment we're going to output this as plain text we're going to paste all that html as we copied it from jspin and i'm just going to go and click on done and we don't need to do anything with http response so the last step over here is just to link these nodes together all right so how do we link these nodes together you just go and highlight on the one port of the node and you can hold and drag your mouse onto the other and let go and now these two nodes are linked and you can do it either way there we go those two nodes are linked as well we've created our very first flow it's basic but we've got it okay so i'm gonna now now we need to deploy this it's not good enough that we've just linked these together it exists in our ui it does not exist on the server-side layer of node-red so in order to deploy it all we do is we click on the deploy button on top and we can see successfully the deployed thank you very much now what do we do how do we actually access this html content well we first need the host name and port and then we need the path that we created all right so it will be localhost 6020 but it's not fort slash weather forward slash dashboard okay do you see over here the url will be relative to forward slash api all right a little bit misleading but we actually defined this in the setup of node-red and all they're saying is that in order to access these endpoints you have to add the hostname the port and then api and then whatever custom url or path that you defined over here all right good so let's go to a new browser tab let's paste it and then we'll say api forward slash weather forward slash dashboard and if we hit enter there's our web page so how's that for delivering html as a service huh pretty cool now keep in mind this is all static but it's functional if i hit enter we've got a we've got validation over here if i provide a search term like let's just use janus book for now all that happens is it reloads the page it provides the search term on top janus book but nothing else is happening this is all static for now we're going to change that shortly now step two step two is to go and take one of those open weather map apis and we need to now expose that api through node-red so going back to node-red over here what we need to do this we first want to test the api okay so we're not going to just go ahead and create this flow already we want to test and how how do we test well it's easy we can use an inject note that way we can manually trigger the flow instead of having to reload web pages or anything we can just trigger the flow right here this inject node is pretty cool it allows us to provide all kinds of snippets of information via message.payload or topic and you can go and actually add more but it's also got the ability to run on an interval and this is how you could shed your flows for for you know you are going to have flows in future that could that might need to be scheduled and this is a great way to do it so the inject node is very powerful it offers you quite a lot but for now we're just going to leave it as default because we're just testing the api for open weather map now to test that we also need an http request node now i've showed you how to do searches on the left hand side i've showed you how to collapse and expand but what i haven't showed you yet is a nice little shortcut where you can do a control for windows or command and just left click on the workspace and you'll be able to actually do a quick search for a node instead of having to go to the left node palette in order to find it so in my case i want an http request node so i just typed http request and i click on that and there we go there's my http request so i'm going to link this over here and what i want to do is i want to just paste the url as i have it in postman so let's go to our first one and i'm going to just copy everything the way it is right here and i'm going to go back and i'm going to paste this and we want to return a pass json object okay otherwise it would just return the json as as text plane so that's everything that we need i can click on done and but if i deploy this now and i run this it runs but how do we see what happened so it's like one of those flows that doesn't actually do it even though it does anything there's no way to to see the result so what we need in order to see the result is we need to actually use the debug bar on the right hand side and by using the debug node on the left we can now go and link the http request and then it will deliver the response to this node and this node is linked to the debug tab on the right hand side of you very very cool so if we click on deploy again and now we run it there we go this is the response that was returned for my http request which was fetching the current with the forecast from openweathermap now just a quick note on message.payload all right we're going to get to the message object soon enough but what you need to know just for now is that most notes deliver content to the other node using payloads and that payload is available via message.payload and that's why by default the debug note said i assume you want me to display the payload on the right hand side over here all right now what's important about this is that the message.payload does not persist in most cases because it will get overwritten by another node using the payload so payload is a very very temporary uh property of the message object and in a short while i'm going to show you how we can take advantage of the message object to store a lot more information that won't be overwritten now while this http request works and it does its job this is not really going to work for us because it's a static url and we need to change the search term over here there we go we need to change the search term so that it's dynamically provided instead of it just all existing over here now in order to achieve this we have to ask ourselves okay but how can i dynamically provide a value over here versus just pasting the url as it is right here into the field and then clicking on done well the answer to this is to understand the documentation of the node we're working with and what's great about node-red is almost every single node that that is available through node-red has got its own documentation which you can access on the help tab over here on the right-hand side so we can see now that the http request node has got a description and it shows you the inputs relative to the message object that you can use in order to dynamically provide values should you not want to use the actual interface all right so we can say yeah the url so that's message.url if not configured in the node this optional property sets the url of the request so what are they telling us they're saying if we have not provided the url over here then the node goes and looks for message.url to see if there's a value there and we are going to take full advantage of that right now so to dynamically provide the url we're going to need to add a little bit of javascript and the best way to do that is to use the function node so i'm going to go and grab the function node on the left hand side and what i'm going to do is just for now i'm going to open up i double clicked on the function node and i'm going to just paste this value over here a lot of the javascript snippets i'm going to be pasting to save on time i don't think anyone wants to see me type out javascript in this demonstration so all i did over here is i provided the url so you can see this is the very url that we we pasted into the actual node but what we're going to do now is we're going to say okay fine how can we now replace chicago with something dynamic so firstly in order to achieve this we need to first know how we're going to get the search term from the incoming request okay well let's put this on pause for a moment and let's go back to our weather dashboard endpoint so what we're going to do is we're going to temporarily use this debug node and we want to see what comes through from the weather dashboard endpoint whenever a request is submitted so we're going to click on the debug node we're going to clear here so you can click on delete to clear your console and i'm going to change this from message.payload to show me the entire message object this is great for debugging and troubleshooting if you just want to see one property of the message which in most cases is payload that's fine but usually when i'm troubleshooting i will say show me the complete message object because it's not only payload that gets populated many other properties in the message object are populated as well right so now i can click on deploy and if i go here and i select this and i click on search i can see there we go the request came in and it got written to the debug tab and i can see there's our search and that's brilliant but if we go and click on the information the help documentation we can see a lot more about the http endpoint for creating the service so we can see payload for get request contains an object of any query stream parameters otherwise contains the body of the http request so in other words if it's a get request it just returns the query stream parameters which is perfect for us if it was a post request it would have returned the body content instead and if that was the case where would we get the request query parameters well if we search down and we can see now that there is a request object in the message object and it it provides us pretty much anything related to the request that occurred so there's the headers there's our query parameters there's and there's additional parameters as well that we can make use of and there's our response as well okay so that's great we've got a lot more access to this http endpoint than what we thought so if i go back to what was printed out over here and i expand request i can see there's headers okay so there's header information that came through there's query and there's a search term that came through i usually do my best to stay away from message.payload because it is a temporary facility and i want to make use of this permanently for this entire flow so i'm rather going to reference the request dot query dot search so if i now click on this function node let's change this to a template string let's just expand this a bit more thank you and i'm going to replace chicago to dot message.request.com dot search now this url is a lot more dynamic so we can click on done and let's go and fix this up now so now we want to put this between the check node and the http request but instead of the one way to do it is we first delete the wire and then we link it again so that's one way of doing it alternatively what we can do is we can actually just drag the function node and you'll see the y becomes a little bit striped and now it links itself so that's perfect so all we did over here is we're overriding the url which means we can clear this because we don't need it here anymore it will be dynamically determined so let's go put this over here and click on deploy and let's test this okay so that didn't come through of course it didn't come through i'm being silly so what i'm going to do over here is i'm actually going to take this wire and this is cool because you can actually make one output trigger multiple inputs so like in this case i'm still going to deliver the response to the web page but then i wanted to also run this function and deliver that to the debug node very cool click on deploy we can go and refresh this and let's see what was returned okay so that's great we can see it's still working that's good news so let's change the rules since it's going to uh make it uh yeah actually it is working at wash chicago what am i saying no it was chicago and now we can see that it actually returned johannesburg instead and there's all kinds of information there's our country code that's perfect all right so now we've made our request a little bit more dynamic okay so moving on we are now going to put in a little bit of better practice this this url over here is a little bit too still too static there must be a way that we can maybe go and put the app id somewhere and put the unit somewhere and reference that whenever we need it well the good news there is what we can do here is we've got context we've got state in node-red and we've got a node state flow state and global state and what this means is we can actually go and set properties and values outside the scope of this flow to be made available whenever we need it so what does that mean it means like things like our app id we don't need to determine our app id inside the flow it might be something that's more generic and could be used elsewhere in node-red as well so we don't want it sitting over here inside our code we want to move this out so we could now place it inside the flow or the global context of node-red now what's the difference between the two on top this is usually what gets regarded as a flow or flow tab and if i double click on this you can see it is regarded as a flow i'm going to rename this and what i'm going to do is i'm going to create another flow tab and it's just i'm just going to call it another tab all right now if i store values property values like key value pairs inside the flow context that that key value pair will only exist for the flow tab that you set it for it will not exist inside another flow tab as well so for example i'm going to go here and i'm going to use the inject node and i'm going to use a new node called change so change node just allows us to sort of set values manually so we can see vr what do you want to set okay i want to set the flow dot and we can say open weather map app id so i want to set open weather map app id 2 and i'm going to go and try let's go and get that value over here all right so i want to go and set it to that and now i can click on done so once i've deployed i can trigger this change node by clicking on the inject node and it will go and set the flow values and if i refresh it over here i can now see that the open weather map app id is available for this flow but if i click on another tab and i refresh it's not available for this flow tab so that's the context it's only available for the flow tab that you're in if you wanted to be available for all tabs then you need to set it on the global context the global state and not the flow state so that's the difference between the two okay so there i've gone and set the open weather map app id why don't we go and set the url and the units of measure as well so what i'm going to do here now is i've just copied some javascript and i'm going to overwrite i'm going to paste over what we've had over here but let's go through this quickly so now message.url is equal to flow.get and there's our current one current forecast so that will get our url for the current forecast which i just need to go and change that prop then the app id is flow dot get owm app id and units is flow dot get owm units so if we go back over here we've got own app id there's owm url current forecast and owm units and i can drag this around if i want to maybe sort it in a certain way so that's great so now our function is looking a lot more dynamic and finally we return the message.request.query.search so let's go and click on done over here and make sure that this is working by clicking on the deploy button and going and changing this to be london oh so that's uh yeah this is the fun times of troubleshooting what's happening is every time i click on deploy nothing happened over here i did not trigger this i did not inject this into the flow state but this is a great this is actually a great tip in the inject node you have an option a checkbox over here inject once after 0.1 seconds we want if we select that every time we do a full deploy it will automatically inject the values so if i now click on this and i try that again now everything worked because the the flow context has been updated with all these values so our flow is starting to look like something but we need to clean this up a little bit and what i love to use when cleaning this up are three very very powerful nodes so the first one is a comment node and you can actually see it's available on the left hand side but if i do a control click then i can search for comment as well and there we are so the comment nodes allow us to label our flows and structure them providing more transparency on what's happening it's also got the ability to provide markdown and which will appear on the information or help tab on the right hand side when you do highlight the comment node but most of the time i will just use it in order to provide labels on what the flows are and where they are inside the flow and so on and so forth so for the first one i want to go and create a comment for our top flow where we're going to set in memory variables there we go and i can copy and paste so you can copy and paste nodes whether you highlight them like this by holding down the mouse and selecting or just highlighting one and ctrl c ctrl v or command c command v and it will just duplicate the note that you highlighted right so now why am i doing this let's go and highlight all these notes and let me just drag them down so i hope you all realize that i'm slowly teaching you a few things that you can do remember this is about node-red basics so i'm showing you how to navigate highlight do this do that please take it all in and realize that you're actually sort of getting a lot of compound learning in one in one sitting you're learning all kinds of things about node-red that's the purpose okay so on top of er we're going to do set memory variables that's exactly what this flow is doing on top here it's setting the memory variables and it's it happens independently of this flow that's running underneath this is the weather dashboard flow all right so let's drag this down over there making it a bit neater now i'm running out of space as well so if i want i can actually hide these pellets or in the sidebar all right so you can see there i'm showing and hiding and the sidebar over here i can actually drag to open and close so the moment i start running out of space i can just do this and let's see how far let's see how long i can last before i actually need to open up one of these again now you can imagine that the moment we start throwing a number of additional nodes how do we start making this look proper and clean and not start to confuse a person when you are 30 40 nodes later on and the answer to that is to use what they call link nodes i'm going to do a search over here for link in and i'm going to do another search for link art these nodes allow you to basically do a stop on the one line and then start on a different line over here so let's let's go and have some fun with this what i'm going to do is i'm going to create another comment node over here this is where we finalize the output and the output is delivering the html content and writing to the http response so that's the finalized part of our flow so now how do we get from if we take a look at the weather dashboard as well the first step is to get current forecast that's our first sort of step over here it's prepping the function this is a prep and then we are get current okay and let's maybe just make it owm for open with map get current how do we get from here to here to here and that's what these link nodes do right so i can put a link node over here and this is where the link in node this is sort of where it starts and i'll call it uh get current forecast it's not compulsory that you call it this but i like to do it otherwise you start landing up with these ids and it just makes things trickier when you're starting to troubleshoot so we've got that and now we can link that to our prep and that provides that now in order to get to this link in we need to use a link out and we just place that over there and we link it so this year well i'm going to say our run get current forecast and you can see i can either go and select this over here to say listen i want to link this node to that node i can either do that by doing this over here or i can drag the port and connect the one port to the other like that so now we can see that when this runs and hits this link in node or sorry link out node it's going to travel to this link in and it's going to just continue working with these notes and in doing so we can now start cleaning up our flows to be a lot more readable and a lot more structured so when it comes to actually creating advanced production based flows this is a very very good practice so i can copy and paste this linking over here and i'm going to just double click on this and change it to say finalize and i'm going to deselect that otherwise it's going to be linked to the top be careful when that happens when you copy and paste and i'm going to now link that and i'm going to copy and paste this one over here and i'm just going to double click on this and say run finalize and now because i provided proper labels i can right here go and select which one i want to link to and we have now got a proper flow from the first point to here to there and now we deliver the response let's click on deploy let's bring out the sidebar now nothing will be printed to the sidebar but what i'm going to do is i'm going to actually add a debug node just because so that whenever something does run we can see in node-red what is happening i'm just going to refresh the browser here okay it still worked there's our request query we we're good everything is working well so if you're still with me at this point and you're enjoying this video do me a favor give it a like i really appreciate it and if you want to stay tuned for a lot more videos like this be sure to subscribe to my youtube channel where i will be posting a lot more recipes and flows and advanced techniques and all things around moderate keep in mind that my channel also focuses on node.js and the moon stack and if you've got any questions don't worry about it just post these questions as comments underneath this video on my youtube channel i respond to every comment i will do my best to try and support and assist you in understanding more of what we're doing over here now that we've got the basic of our flow sort of in place we need to now start making this something and the first thing that we need to do is we need to try and start handling errors or queries that might not make any sense so for example let me take this debug node quickly detach it over here and let me go and put it over here by the way we get the current forecast and what i'm going to do is i'm going to go and search for test now this is something that won't it will get through to our node red flow but it doesn't actually return anything if i expand and i see what the payload of this request is i can see it returned a 404 city not found okay that's brilliant so now what we need to do is we need to understand that this could happen when people are searching and they might add spelling or typos or whatever and we need a way to handle that and deliver the response to the user as well so what i'd like to do over here in this exercise is i actually want to do two things i want to hide these panels if it's a new page if they're opening it up for the first time i want to hide these panels and if an error occurs i actually want to display the error message over here so that's that's what we're going to do next so to handle incoming errors the first thing we need to do is let's go and create a comment node and let's just see we'll call this catch errors and now we've actually got a node called catch and it works like a try catch so it will actually catch any kind of error that is thrown through any of the nodes inside this flow tab so we just put this over here and we'll say catch all nodes thank you very much we're now going to take the message object and we're going to or the debug node sorry and we're going to place this over here for now so that we can see what the output is if i click on catch node and i go to the help i can see over here that the output of the catch gets written to message.error okay so a message is assumed so it's message.error and then we can see additional properties that will get written to message.error as well so that that's great because what i can do over here is i can change this to right to the console message.error that is what i'm interested in right now but also if i don't let this run towards the output we're going to have a problem over here towards the finalize so if i go and run this and now let's go and add test which is a problematic value oh okay so the problem is it's still it's it's not getting to the catch error it's getting stuck it's going straight to finalize why is it doing that it's because this year only handles errors that are thrown the response from the http request even though it's returning a 404 response it's not it's not actually a javascript error it's just a negative response from the http request so we have to still convert it into an error and to do that we can go and grab a function node and place it after the http request before it goes to the link node and over here we can say we want to process result so let's just keep this clean and i've got some javascript that i'm going to paste inside here and all i'm doing is i'm saying okay let's check the response for an error if the message.status code which we learn as well if we looked if we read the documentation over here we'll know that the response the response code gets written to message.status code if it's anything greater than or equal to 400 then we have to handle it so all i do over here is to i try my luck and i assume that because it's open with a map they are going to deliver the message or the error description to the message dot payload.message over here otherwise if that doesn't work out then just return the entire message.payload and i'll throw that as an error so it's just like a safety net but ultimately this is what should happen all the time once i've now got my error message ready to go i throw the error error message which now will get caught by the catch node all right now can you see the web page is not the response has not been returned to this webpage why it's because we got to the catch node and we wrote the error there we go perfect okay but from here it's not going anywhere else we have to go get to the finalized store we have to still deliver the html content so i'm just going to copy this link out node and i'm going to link that over there and now if we deploy this and try again it will still come back to the web page perfect okay we haven't broken our flow we're getting our error but we haven't broken our flow now what i would like to do is i would like to display this error as well as the search term they used and display that in the header of the static html page now we finally get to the part where we're going to start modifying and turning our static page into something dynamic so in order to do that what i need to do here is add a function node let's just move that out and just put this over here and i'm going to call this prep error and i'm going to paste some javascript logic over here and all this is doing is we are writing to the payload we're writing a header prop and the header prop is whatever the message.error.message is okay as well as the message.request.query.search that will give us our first that that will give us error city not found and then the search term that was used so that's perfect notice what i'm also going to do i'm going to delete the message.request.query.search why am i going to do that you'll see now earlier on i mentioned that i don't want these panels to show if there is no search query or if an error occurred okay so if what i'm going to do here is i'm going to delete the search query when an error occurs so that the page so that the final logic knows that it can do something with that now that there is no search term so hit that to the link node now how do we get the error message written to the header over here well first let's remember where we put it okay we we stored it in message.payload.header we need to remember that okay now if we open up uh the template node and if i just go and add a new one here they kind of show you quickly what to do so if i say a new template they show that you've got whatever message or text that you want but notice what they're doing they're using double curly double left curlies double right and they've got a value inside which is just payload now what what they do in our vi is they telling us that you can actually dynamically in insert values into the static content inside this template node what they do is they allow you to reference the message object in order to determine what values you are going to dynamically write and it does this using a module called mustache.js similar to handlebars it is a templating engine that allows you to take static templates and sort of provide dynamic content into them with the with a lot of wonderful little bells and whistles and it's exactly what we're going to be using so just to know more about mustache.js there's the url i will be providing links to all of these websites and you can see mustache is available for all kinds of environments and programming languages we're going to go on javascript and that opens up their github page and you can see crazy dude you know with these mustache cool and then they just show you like all kinds of ways that you can just use mustache so what we're going to do is we're going to use mustache to overwrite the header so i'm going to remove that template and i'm going to go to the one we are using that has our html content and i'm going to search for this chicago united states which is a static value at the moment so i'm going to remove that and i'm going to replace it with mustache tags so it's it's two open curlys two close curlys and inside there now i want to store the value of the error message that was returned which i don't if you remember but it was message.payload.header now i don't write message.payload.header yeah okay messy it's it's relative to the message object and that's what they showed earlier on when then that's why i showed you the other template node is that they showed you you must start with anything from the message object so in our case it's payload.header we don't need to we don't need to specify message it is it is relative to message so now that we've got that over there let's click on done and see what happens first things first if i don't provide any search term then there should be no header instead we get a bad query undefined where did that happen process result okay so we got a bad query oh and the reason why we got a bad query that's actually brilliant the reason why we got a bad query is because there was no search term so when when we reached this point there was no search term but now it goes and tries and still gets the current weather forecast without a search term okay so now we need to enhance it a little bit more and what we're going to do here is we're going to introduce a switch node so the first thing is first over here instead of just a command click on the workspace or control click i'm actually going to command click on the wire and i'm going to search for switch and what happens is it gets automatically linked how cool is that all right once you get these shortcuts out the way then you you start really improving and and getting faster with with flow development in node-red and in case you're wondering how do we know what the shortcut shortcuts are click on the information tab over here on the right hand side and you'll see at the bottom there's your shortcuts tips and tricks and you can just refresh them and it will show you all kinds of weird things that you can do in node-red cool all right so now we've got our switch node which works like a javascript switch and we can say what are we checking what is the property that we are referencing we want to reference message.request dot query dot search and we want to say is it is it is not empty there we go we got a lot of options is it equal to greater than all kinds of crazy stuff but all we want to say is is it empty or not if it's not empty we want one of those conditions and we want to add another condition which is otherwise so that's this that's the same as a switches default so there we go otherwise so it will first check to see if it's not empty but otherwise anything else it will reach this part of a year and instead of checking all rules i will say stop after the first match click on done and you'll see that now we've got two output ports so the condition is is not empty and this one is for otherwise what does that allow us to do if no search term was provided just return the web page don't run any of the apis okay currently this is running going to get current forecasts which is fine if it's not empty but if it is empty we want to go straight to finalize at the bottom so let's go and grab this link out copy and paste it put it over here do you see so now if we deploy this and i refresh this our error goes away so that's brilliant now let's go and search for a town that doesn't exist there we go city not found test that's exactly what we wanted to do and they can still try again so we can say i want to search for test2 city not found test2 but i also want to hide this i don't want to show these panels if there's nothing to show so on a new page or on an error i want these to hide now remember in the node-red what we did was when an error occurs then we delete the search query okay so on first load of a page there is no search query so we already know that it will not exist but if an error occurs we manually delete the search query and that way we can now go and add a little bit more intelligence into our template so what i'm going to do here i am going to grab a part of this and this is a bit let's see if we can get there we go that's a little bit better and all i want to do is i want to grab everything under the header and i'm going to use some mustache and all that's going to happen is this we can actually use message.request.query.search and we can actually do in conditional statements over here by using hash and remember we don't specify message as we it's relative to message so it's uh request dot query dot search and over here i'm going to close target and what's happening over here we're saying if it exists that's the same as saying if message.request.query.search is not equal to null or undefined or blank for that matter then deliver the response of this data to deliver the output otherwise don't deliver the output so let's go click on done deploy it and let's see this in action firstly loading the page for the first time great stuff so now let's go and use a an error great it's still not showing the panels and we're still getting our error message over there that's brilliant so let's go and put a valid value like uh like london okay so that's that's awesome it is working now that we've got error management out the way and our web page is a little bit more bulletproof what we're going to do now is we're going to finalize the the current forecast so how do we do that over here first thing is we need to now manage the response data that came back from the get current forecast which means we actually need to store this data somewhere so this is where i quickly want to introduce you to the message object and help you understand how it works i'm going to use an inject node and i'm just going to shoot straight to a debug node and i'm going to say the debug node must show us the entire message object i'm going to click on deploy and i'm going to clear my debug console and i'm just going to click on this trigger over here whenever a request begins whether it's by an event that is like an http endpoint or scheduled task or a listener like a catch node or even the timestamp over here the trigger the inject node whenever an event is triggered and a flow begins okay a message object for that transaction is created and the message object is only available for that transaction let's put it this way if six requests for this where the dashboard endpoint came in at the exact same time they will not share the message object a message object will be created for each of the six requests and the message object exists for the duration of the flow until it's completed all right so if we take our weather dashboard from here the message object is created it exists it exists it exists it exists it exists and up until this point once the response is delivered only then is the message object removed from memory right so this over here shows us that the simplest flow that you could create this is what gets written to the message object it's got its own id it's got a topic and it's got a payload now what do we know we know that payload is temporary and in most cases will be modified once it comes in and out of other nodes but what's nice is we can use the rest of the message object to store temporary data that will persist for the duration of the entire flow it shouldn't be overwritten unless you accidentally used a prop value that gets used by another node but it's usually highly unlikely so what we want to do is i want to store the current forecast i want to store the five day forecast i want to store this data from these apis i want to make it available and store it inside the message object so that it's available when i need to work with that data in order to make the html dynamic to do this we can actually go and use a change node and go and set the message object on whenever this endpoint is triggered so i'm going to click on this wire and i'm going to add a change node there we go and we're just going to say prep response and all i'm going to do is i'm going to say set message dot result is equal to and i'm not going to make a text i want to make it to an empty json object okay because we're going to use this later on i need to store this so message.result so what happens over here now is whenever this endpoint is triggered the message object a result property will exist and it will be an empty object now what i want to do is for our current forecast i want to go and add a little bit of intelligence over here because currently we're just managing the error but what i want to do is i want to go write some code so that we can fix up the incoming data because the incoming data from the open weather map api is a little bit too raw we want to fix it up make it a little bit neater so i'm just going to go grab a javascript snippet and i'm going to overwrite this over here and let's go through this to see what's happening so this was our error on top we're happy with that but now we want to say process response data so what am i doing over here i'm saying message dot country code so yes he has a good example of hum adding a new property to the message object because it's available to me and i'm saying message.country code is whatever the message payload says country is which is the response i got back from open weather map so i'm temporarily storing the country code because i need to use it when i call the country api all right so there we go our country code is stored then message.result.header now look there message.result i know i can i can assume that message.result exists because when this flow starts we that we use the change node to default it to an empty object so i'm saying the header is whatever the name of the town is the name of the search is like london or janisberg that will be the header for now then what i do over here is i go and grab their sunrise values which is like a unix timestamp and their sunset is also unix timestamp and all i do is i just use a little bit of logic over here to convert it into something more readable but notice i'm using date flow.getdateparams there's some rules around this how i want it to look and instead of manually specifying it over here i say listen yeah just go and reference it in my flow context because it can be used elsewhere so let's go and do that quickly and i'll go up here and i will go and add set flow date params and i've got it over here it's json and let me just show you what this looks like you see so it's just the parameters for that to local string and i'm storing it in the flow context because it's much better practice and coming back to the process result we can now read the rest so that takes care of our sunrise and sunset and now look at this dot message.result.com so i'm creating a new object in message slot result called current which which is our current forecast and inside there i've got description the icon you'll see that now the temperature and i'm just doing a little bit of rounding oh and we need a temperature unit as well sorry because if it's a fahrenheit we use a certain character if we use metric we use degrees celsius so instead of manually providing that all over that can be something that is configurable via this over here so i'm going to add a new one there we go and i'm just going to drag this up so that it sits with metric over there coming back over here so that takes care of this temperature unit as well which we use for the temperature and feels like and then we've got humidity and then sunrise and sunset which we're defined over here we return in our javascript in our function nodes you always have to return the message object you always always always have to return it's just one of those things by default we cannot remove this it is not assumed always always always return the message object great so there's all there's our javascript logic nothing hairy we're just cleaning up the response data and now that we know that this is what it looks like we can now go and test this and what i'm going to do here is i'm going to remove this and i'm going to put this over here and let's deploy and let's go and do a run search for london okay so it's great that this still works and now we can go here and expand the message object because we i'm print i'm outputting the entire message object and you can see there's result there's the header london brilliant if we expand current there we go light rain the icon temperature wonderful we've got our information we've got our data from the api now we can go and update the html content so we under current forecast so yeah we've got broken clouds i can now go and say but that is not broken clouds anymore that is result remember we don't have to specify message result.current.org and then icon look at this so if we take a look at this dashboard there's all these icons over here but we need to dynamically determine the icon and open where the map tells us what the icon code is for the type of weather that's occurring so instead of manually providing the icon the rest of the url is always the same it's just the icon code that changes so i can save the result that was going to hurt me result dot current dot icon there we go that takes care of that and now we can just do the rest and that should do the job so let's click on done here we've done we've now modified a lot at the same time but let's go and refresh this so firstly let's blank that's fine and i'm going to go and choose johannesburg clear skies all right let's try london light rain okay all of this is working brilliant so we haven't got a header that's something that's not working right now so if i just go back here and i see message start result.header let's go back and see how why this is not quickly working we're doing payload.header okay that's not going to work for us so what we need to do here is we need to say message.result.header and the prep error should be dot header message.result.header as well we will test that shortly so there we go london and if we say test that still works okay perfect everything is working as it should we are now done with the current forecast all we need to do the worst is over it's mostly copy and paste now all we need to do is do the same for the five day forecast as well as for retrieving the country data right welcome back everyone so all i've done over here is i've copied and pasted these two for the five day forecast and the country info which i will take you through shortly and i just did a couple of updates here and there uh in like updating the html content and adding one or two uh change flows so if we just go for the five day forecast you'll see that this once this continues for the current forecast we'll just link it to go to the five day and all we do in our ya is very similar to the current forecast all we're doing is we're referencing the five-day forecast this i went and added into the change node as well so that that url is available this was already there and there's our search query so nothing crazy over there nothing happening over here it's exactly the same as this i just changed the label to say get 5 day and over here is the result this is exactly the same as the previous one the only thing that changes here is the logic that i used so you'll see over here message.result.5day is now an array because we actually want it's a it's a table in that panel in the ui and all i do here is i loop through the content and i go and format and return the data that i want to be using from the five day forecast and i push that into the five day array and all i do at the bottom is i only need five entries i'm using the one that returns 16 days so the moment i reach uh the fourth or the fifth entry inside the array i break out of the loop and return message so nothing crazy from there i go to fetch country info which i do a prep as well this is a lot easier because for the country info i use the url which i provided over here in the change rule and i just reference message.country code which i populated i don't know if you remember but i populated over here so i go and store that i i use that for the country info over here so that's fine and you can see i copied and pasted because this is get five day it should be say get country info and it's not open with a map everything else is the same it was just a label that changed and now we process the result of this again we have an error check to make sure that we can provide a descriptive error message and all we do here is we instead of the header just showing the town or city you searched we include the country so i get that from the country info so i just added that over there and all i'm doing is i'm grouping some currencies because there could be more than one i grouping languages because there could be more than one and message.result.country is equal to all this information everything i pretty much get from the the api call so if you felt like you were done in with me copying and pasting you'll see that not much was missed and all i did now was in the html content i go and reference so this was the current forecast and yeah on the five day weather forecast you'll see i'm referencing um the the open weather map and you can see i'm using mustache to loop so the same way we did a condition is the same way you can loop through arrays of json inside inside your json payload and that allows us to dynamically create as many table row entries in our table based on the amount of entries that were inside the array and if we get here to the country panel you can see that i'm referencing just result.country and there's all the details relative to it and everything else has stayed the same nothing else has changed so we almost at the end everyone okay let's go and test this let's just move this up a little bit here for my ocd thank you and let's go click on deploy and now let's go and test our application so if i refresh this and i go and say okay fine let's see if there's errors oh there we go managing errors properly let's click on janisberg click on search and there's our data so current forecast everything's working and five day forecast there we go you see the header is now the town or your search term as well as the country and now we get information about the country including the flag the code the capital the population and check how many languages we have in south africa right so we try change this to london london everything changed we've got a brilliant working weather dashboard now the final little easter egg just one more little scene that i'd like to show everyone before we call it a day is what if you wanted this data as an api as a json result instead of it producing html what if we said let us go and say that if you don't provide the output then we assume it's html otherwise if it's json then why don't we go and just change the rules to return the json content instead of returning the actual html so let's quickly go so over here i'm going to add a switch and all i'm going to do here is i'm going to say check output i'm going to say message.request.query if it's equal to json then it will do one thing otherwise we will just resort to html uh we want and we want html it must happen on the otherwise so we'll link that over there what we need over here is we need a change node and we want to set message.payload to message.current all right apologies everyone i'm being silly over here so i say that we must deliver the current and provide that to the payload but obviously that's not the case we need to provide the result message.result must be set or message.payload must be set to message.result a little bit of a brain thought on my side it has been known to happen all right so if i do a search term here for london as an example i get the dashboard which is great but if i just go and add and output is json i will get the json instead of everything that was used for that web page so that's great now it's just become an api that that people can consume and if you thought that the easter eggs weren't done yet what if i wanted this i was working on my local development environment now what if i wanted this on an online environment now that i'm happy with it and it's ready to go how do i deploy this to another node-red instance that's actually available on the public cloud now at agility we've got a lot of node-red instances everywhere so i'm going to show you how you can take these flows and you can export and import them into another node-red environment and watch how quickly you can immediately just use it on the right hand we've got our burger menu over here and you see we have the option to say export now you've got a lot of options you can either select nodes and only export a number of nodes or one or many or you can export everything within the flow tab or you can export everything that has been created in this node-red instance now in our case we just want the flow tab so i click on current flow and i can either download this as a json file or i can copy this to clipboard which is easy enough and what i'm going to do is i'm going to go to our online testing environment this is a node-red environment that is available on the agility cloud and this is actually it does a number of things unit testing and all kinds of stuff it's actually an online testing ecosystem that makes sure that our product agility is working and everything happens as per it should that's why you'll see a whole bunch of scheduled timers and all kinds of crazy things so what i'm going to do is i'm just going to go and say i want to create i want to import this i don't even have to create a new flow tab i can just say i want to import i can paste the content or if you saved it to a json file you can select the file and you can say import it into a new flow tab i can click on import there and you can see it got added as a new tab there's our flows i'm going to go ahead and do a full deploy and what i'm going to do is i'm going to grab this so we know it's where the dashboard but i'm going to take this url over here and very similar to our local i'm going to paste this forward slash api forward slash weather forward slash dashboard if i search for chicago there's our dashboard working we just deployed our node red from our local to another environment and that's how easy it is to to work with node-red once you know what you're doing so that concludes this live demonstration for today it was a big one but i'm sure that with everything that you've learned today there is just so much that you can already go away and do in node-red there's obviously so much more that i need to teach everyone but this should give you a lot to go and already start working on node-red and building your flows and building your integrations thanks very much for watching
Info
Channel: Bleeding Code (By John Jardin)
Views: 19,003
Rating: undefined out of 5
Keywords: how to create your first flow in node-red, node-red basics, first node-red flow, node-red flow tutorial, node-red flows tutorial, node red flows tutorial, how to create your first node-red flow, how to create a flow in node-red, how to create a flow in node red, node red basics, node-red fundamentals, Node red flows, node-red flows, node-red weather, open weather map, nodered, node red tutorials, node red, node-red, visual node js programming, node-red tutorial youtube
Id: cVWVr_T7kQ0
Channel Id: undefined
Length: 68min 37sec (4117 seconds)
Published: Tue May 25 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.