How to set Heroku Port for NodeJS Express App? - javascript

so I'm trying to host my website on Heroku and set up everything to get my app up and running.
Whenever I try to submit the form I get undefined errors.
Undefined Errors Console Errors
I've set it up to use the port like shown in the documenation:
app.listen(process.env.PORT || 8081, function () {
console.log('Example app listening on port 8081!');
});
When starting the app locally with heroku local web I get Typerror: Failed to Fetch and the undefined results but when I go into my .env file and add a port=8081 it works perfectly fine.
Good result
When I open it with heroku open I still have that undefined problem.
I don't really have to set a PORT in .env right? Or do I?
I read that that standard port is 80 but that didn't work either.
Can someone please help me?
Thank you!
Heres the link to the public site: https://shrouded-everglades-61993.herokuapp.com/
Here the link to my Github rep: https://github.com/stefanfeldner/capstone-travel-app

So the reason that they're undefined is that they are being set by these lines in main.js:
uiData.imageURL = data[1].imageUrl;
...
uiData.iconCode = data[0].iconCode;
Where data is the object you're retrieving from your /getData endpoint. The problem is that what /getData actually returns is [{}, {}] so of course these values are both undefined, leading to that visual broken-ness.
Now, why does /getData return these empty objects? I can't check your server logs, but there are two obvious possibilities based on the way server.js is written.
The first is that there's an error somewhere and you're simply not making it all the way to the end of your try-catch in callApi, so neither weatherData nor pixabayData are being updated.
Second, it's also possible that these calls are successful but that the desired data is not in the results, i.e. that neither of these if statements are true:
if('city_name' in data) {`
...
if('hits' in data) {
Again, in this case, neither weatherData nor pixabayData are being updated.
The way that your handler for /sendFormData is written, it doesn't check that callApi actually got any useful data, just that it has finished execution. So your code flow continues on its merry way despite the data objects still being empty.
However, there's a bigger, unrelated design flaw here: What happens if more than one person uses your website? Your client-side code calls /sendFormData, which hopefully correctly populates the global variables weatherData and pixabayData, and then separately calls /getData to try and retrieve this data.
The thing is, though, between the time your client-side calls /sendFormData and /getData, anyone else using your website could separately call /sendFormData and change the data contained in the global variables from the result of your search to the result of their search. So you'd get their search results back instead of yours, since their results overwrote your results on the server. You need to handle getting the API results and sending them back to the requester in a single transaction.
(Re: all the local Heroku Config, that's hard to answer without messing around with your local computer, sorry.)

Related

Having a hard time getting Api from localhost?

I am on this project wherein I need the api from this specific software. I cannot fetch it when I am trying to fetch it, sometimes error 404 are occuring,
sometimes no-cors policy.
Then sometimes like this: GET http://localhost:8000/events/1003/results net::ERR_CONNECTION_REFUSED
getEvents # orbiter.js:22
(anonymous) # orbiter.js:28
Then sometimes Uncaught (in promise) TypeError:
There are no authorization that needed based on the documentation or headers. Or i thought so it does not have?
But i think this is because of the way that I am fetching the API, it looks like I am doing it wrong. The API as i am trying to get on the instruction on the documentation it says i can access it on "localhost"
At first i just need to open the software to have access on the localhost so the http port will open, then i go to "localhost" then everything is on that local host
This are the picture Screenshot of The LocalHost I need to access
Now based on this I need to get the result of the event. Based on the documentation I need to go to path "localhost/events/{event-id}/results" then a json format would be send back to me.
I go to the url using browser using that path and I get the result, This are the result based on that path but this are the thing, when I am trying to put it on the code using Javascript language es6 module wherein I am fetching the api and I put the link "localhost/events/{event-id}/results"
this are the code:
const link = "http://localhost/events/1003/results";
async function getEvents() {
const response = await fetch(link);
const data = await response.json();
console.log(data);
return data;
}
getEvents();
I cannot access now the data that I needed from the API. Even though the path on the link that I put was correct. Am i missing some steps here? That's all. As you can see, localhost is the main path, then i just follow the path based on the documentation to get the results. (Because what i need to access are the results of the events). Then errors has occurred. This are the documentation that may help you to help me. I hope some of you may help me on this one as I'm still a beginner on programming
https://drive.google.com/drive/u/0/folders/1Il6GPL-pqxeS8OWVOEt36OF-a_FfQwpj

Django/React app API in production vs development?

So I have made a React app that uses Axios to fetch api's. During development, I would have an api call to 127.0.0.1. However, my ReactApp resided on localhost:3000. Therefore, it development, I can't just use:
axios.get('/api/'),
In dev I would need to use:
axios.get('127.0.0.1/api/'),
Anybody have any good ideas on how to resolve this conflict so I can see some data in dev? Kinda tough to design an UI without any data to populate it. Kinda like buying a shirt without trying it on first (which, I never try anything on, so this is a horrible analogy.)
Use it as in the first example. Because it is relative, it will resolve fine for different hosts:
axios.get('/api')
Will automatically resolve to:
// if called by https://example.com/index.js for example
"https://example.com/api"
// if called by localhost/index.js
"https(s)://localhost/api"
In your second example, if you prepend the host and port, you will get duplication!
For example, I just tried your first example on my localhost:3000 and the result is
GET http://localhost:3000/api 404 (Not Found)
Which makes sense because I don't have a /api. But did you notice it appended /api correctly after my host and port?
Now your second example:
GET http://localhost:3000/127.0.0.1/api 404 (Not Found)
It duplicates the host and port. In your case it would be 127.0.0.1:3000/127.0.0.1/api
Just use the first example and it will resolve fine for different hosts (and ports) because it's relative! Did you try it out?

How to bypass an express middleware?

I'm working with an express application. There are some express routes, as
server.get('*' , ... )
etc. which perform some common operations: authentication, validation... etc.
they also decorates the response with meaningful information: i.e. in every request to the server it gives not only the expected json/html, but also information regarding the user, some app metadata that the front-end consumes etc. etc.
Let's say all this extra metadata cames in a field called extradata in every request to the server.
Now, there is a bug that is causing a problem: instead of returning its expected response (a json with a bunch of system logs), is sending only this extradata field.
I'm pretty confident the problem is in one of the middlewares, because that code that sends the response in this case is really simple, it's just a res.send() of a json. So I believe this part of the app is requiring some module that sets a middleware which causes the error. There are a lot of global vars and implicit parameters in the app so is really difficult to debug it manualluy.
I attempted to bypass such middlewares programmatically, like:
delete server._router.stack[2];
but is causing an TypeError: Cannot read property 'route' of undefined and thus preventing my app to build: sure this is not the way to go.
so, is there a way to programmatically ignore or bypass express routes that are yet set?
Even better, is there a way to programmatically tap into express middlewares and log every request and response?
(afaik, there are libreries like morgan that logs every request, but I don't think they apply to this case since I need to discriminate between middlewares).
What I generally do is simply use the next method. You can access it by simply passing it to the callback function. Something like:
app.use(function(req, res, next) {
if(...) {
next();
} else {
...
}
}
What this is going to do is go to the next middleware.
So if I understand correctly, you can check what you exactly need in the if-statement and do things accordingly.
What I would suggest is you read the Express API documentation, especially the section about middleware, which you can find here. Moreover, try to isolate the suspects and solve the issue by removing the problem, rather than deleting handlers and trying to solve the problem the easy way.

Ionic-Angularjs | Write logging to file or variable

I'm working on a new project using Ionic (AngularJs-based) and everything is working as it should be.
I'm currently outputting every 'Function call' (every step) to the console (via a Debug-Function) for debugging purposes so that I can quickly see if every function gets called correctly.
Log Function (minimised/simplified code):
.factory('DebugMode', ['$log', function($log) {
var DebugMode = {};
this.active = true;
this.console = function(LogLine, LogStyle)}
if(DebugMode.active){
$log.log(LogLine);
}
};
return DebugMode;
My question:
Is there a way or a method that I can also write that output (not specific the console output, but the logs I write to it) to a file or variable?
My purpose: Able to request the log when I'm running the app stand-alone and don't have access to a browser or some sort. So that I can easily see if everything is still running correctly or if a client is experiencing some issues, I can ask them to send the Log via mail or some sort.
For ex. (in the app): Open the menu, go to settings, show log, see where the app returned an error and/or press a button to send that log to me.
Would the best way be to write everything to a 'log-output.date().txt' sort of thing or store everything in a session variable that gets cleared on exit?
Thanks in advance!
-Bert
After some research, I think FileLogger would be the best solution and does exactly what I had in mind (more or less).

Database items sometimes not showing up in Meteor.js

I have a simple app written in meteor here: https://gist.github.com/drew-gross/6202629 that is having problems. When the Template.tab.ordered_drinks function is called, no Tabs are found (Tabs.find({}).fetch() returns an empty array) but only most of the time. Sometimes the Tabs are there. I have checked that they exist in the database.
To reproduce:
1) Run the app. (requires meteor-router)
2) Create a tab on the console: Tabs.insert({owner:"foo"})
3) Try to view the page for the tab: localhost:3000/tabs/:id
The page will work or not work, seemingly at random. To confirm, you can set a breakpoint on line 9 or 19 of the .js and do Tabs.find({}).fetch() and you will sometimes see and sometimes not see the tab.
This kinda seems like a bug in Meteor but I thought I would check first to see if I might be doing something wrong.
Browser: Chrome 28
Meteor version: Release 0.6.4.1
Node version: v0.10.15
It looks like the issue might arise if the subscriptions haven't yet got their data.
In meteor the html/js is sent down to the client, it then renders the page. At the same time the client connects to the server via websockets/long polling to retrieve the mongo database.
So sometimes you can render html without yet having anything in your database.
You just need to be careful that you use reactivity to handle when the data arrives and not presume its already there, like here:
Template.tab.ordered_drinks = function () {
return Tabs.findOne(Session.get('tabId')).ordered_drinks;
};
if Tabs.findOne(Session.get('tabId')) is null because there isn't any data on the client (yet) then .ordered_drinks wont exist and you would get an error on the chrome console & sometimes see/sometimes not see the tab, depending on whether the database has loaded yet or not.
Try altering the line below to allow Tabs.findOne(Session.get('tabId')) to be null without throwing an error.
Template.tab.ordered_drinks = function () {
var tab = Tabs.findOne(Session.get('tabId'));
return tab && tab.ordered_drinks;
};
So at this point it is loading. As soon as the data arrives it'll reactively re-render this portion with the tabs.

Categories