Why findOne() doesn't run in my code

Hi all,

I work ’ Apis and Microservices Projects - URL Shortener Microservice’ challenge

I consider to know why findOne() method doesn’t run in the code below.(console.log() in findOne() doesn’t log anything in the console)

Here is my code on the server:
link to my code: https://glitch.com/edit/#!/api-project-url-shortener-microservice-for-freeco-

'use strict';

var express = require('express');
var mongo = require('mongodb');
var mongoose = require('mongoose');
const dns = require('dns');
var cors = require('cors');

var app = express();

// Basic Configuration 
var port = process.env.PORT || 3000;

/** this project needs a db !! **/ 
mongoose.connect(process.env.MONGO_URI);

var Schema = mongoose.Schema;

var url = new Schema({
  orginal_url : {type:String, required:true},
  short_url : {type:Number, required:true}
});

var count = new Schema({
  num : {type:Number},
  name : {type:String}
});


var Url = mongoose.model('Url', url);
var CounterU = mongoose.model('CounterU', count);

var counter = new CounterU({name:'urlCounter', num:0});


app.use(cors());

/** this project needs to parse POST bodies **/
// you should mount the body-parser here
var bodyParser = require('body-parser');

app.use('/public', express.static(process.cwd() + '/public'));

app.get('/', function(req, res){
  res.sendFile(process.cwd() + '/views/index.html');
});

// your first API endpoint... 
app.get("/api/hello", function (req, res) {
  res.json({greeting: 'hello API'});
});

app.use(bodyParser.urlencoded({extended: false}));

function isURL(str) {
  console.log(str);
  var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
    '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
    '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
    '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
    '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
    '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
  return pattern.test(str);
}

app.post('/api/shorturl/new',
         function(req,res){
                CounterU.findOne({name:'urlCounter'},function (err, data) {
                  console.log('findOne runs...');
                  if(!data) {console.log('There is no urlCounter:(')}else{console.log('We have already urlCounter:)')}
                  if (err) return console.error(err);                 
                  })

            if(!isURL(req.body.url)){
                res.json({error:"invalid URL"})
            }else{
                dns.lookup(req.body.url,function(err, address, family){                 
                console.log('address: %j family: IPv%s', address, family);})
                res.json({error:"Valid URL"})
                  }                  
          });

app.listen(port, function () {
  console.log('Node.js listening ...');
});

any idea?
Thanks in advance

It doesn’t look like you saved counter. findOne is probably functioning correctly but what you are trying to find does not exist.

1 Like

Thanks for your reply

I think if it doesn’t exist then based on this line:

if(!data) {console.log('There is no urlCounter:(')}else{console.log('We have already urlCounter:)')}

the console must logged : There is no urlCounter:(

isn’t it?

but the console doesn’t log this.

What does get logged to the console? Anything? If so, can you show it?

Hi There!

Are you actually making a POST call to your endpoint? ‘/api/shorturl/new’

app.post('/api/shorturl/new',
         function(req,res){
                CounterU.findOne({name:'urlCounter'},function (err, data) {
                  console.log('findOne runs...');
                  if(!data) {console.log('There is no urlCounter:(')}else{console.log('We have already urlCounter:)')}
                  if (err) return console.error(err);                 
                  })

            if(!isURL(req.body.url)){
                res.json({error:"invalid URL"})
            }else{
                dns.lookup(req.body.url,function(err, address, family){                 
                console.log('address: %j family: IPv%s', address, family);})
                res.json({error:"Valid URL"})
                  }                  
          });

The code above sets up an endpoint route that can be hit by a web client, such as a web browser. The controller code won’t run until you actually make a request to it.

Hope this makes sense. I can explain further if needed.

Have you looked in your database to see whether or not the data is in there?

If in text box of index.html page I typed “google.com”, the out is similar to this image

It seems all console.log() are run but that one in the findOne() isn’t run and I don’t know why.

I must mention that I already have an index.html page. this send request to the server. this is index.html code

<!DOCTYPE html>

<html>

   <head>
      <title>URL Shortener</title>
      <link rel="shortcut icon" href="https://cdn.hyperdev.com/us-east-1%3A52a203ff-088b-420f-81be-45bf559d01b1%2Ffavicon.ico" type="image/x-icon"/>
      <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type="text/css">
      <link href="/public/style.css" rel="stylesheet" type="text/css">
   </head>

   <body>
      <div class="container">
        <h2>API Project: URL Shortener Microservice</h2>
        <h3>User Story: </h3>
        <ol>
          <li>I can POST a URL to <code>[project_url]/api/shorturl/new</code> and I will receive a shortened URL in the JSON response.<br>Example : <code>{"original_url":"www.google.com","short_url":1}</code></li>
          <li>If I pass an invalid URL that doesn't follow the <code>http(s)://www.example.com(/more/routes)</code> format, the JSON response will contain an error like <code>{"error":"invalid URL"}</code><br>
          HINT: to be sure that the submitted url points to a valid site you can use the function <code>dns.lookup(host, cb)</code> from the <code>dns</code> core module.</li>
          <li>When I visit the shortened URL, it will redirect me to my original link.</li>
        </ol>
        
        <h3>Short URL Creation </h3>
        <p>
          example: <code>POST [project_url]/api/shorturl/new</code> - <code>https://www.google.com</code>
        </p>
        <form action="api/shorturl/new" method="POST">
          <label for="url_input">URL to be shortened</label>
          <input id="url_input" type="text" name="url" value="https://www.freecodecamp.org">
          <input type="submit" value="POST URL">
        </form>
        <h3>Example Usage:</h3>
        <a href="https://thread-paper.glitch.me/api/shorturl/3">
          [this_project_url]/api/shorturl/3
        </a>

        <h3>Will Redirect to:</h3>
        <p>http://forum.freecodecamp.org/</p>
      </div>
      <div class="footer">
        <p>
          by <a href="https://www.freecodecamp.org">freeCodeCamp</a>
        </p>
      </div>
   </body>


</html>

and the output is similar to this:

I’m sure there is no data in the database so based on if statement in the code below:

if(!data) {console.log('There is no urlCounter:(')}else{console.log('We have already urlCounter:)')}

I think console.log('There is no urlCounter:(') must run.

Is it right?

I’m not sure why that doesn’t seem to run, but did you save counter and see what happens then?

Try changing this

<form action="api/shorturl/new" method="POST">

to this

<form action="/api/shorturl/new" method="POST">

The console.log should only fire when you submit the form.

Change if(!data) to if(!data.length) and try a console.log(data) too. We need to know what you are getting back from the database, if anything. data might be an empty array/response.

@shadowfox476 that’s a good catch, but I completed this project and didn’t catch that and it didn’t cause me any errors. It’s part of the boilerplate code. But app.route(“api/shorturl/new”) does cause problems. So I’m not sure why in the html file it dose not cause a problem?

I apologize, I don’t completely follow your response.

There are two separate components to your code

  1. The client - this is what is making the request (ask asking for something). In this instance it is asking for something relative to your root path. http://yourwebserverpath/apishorturl/new
<form action="/api/shorturl/new" method="POST">
  1. The server - this is what is serving up the response. This line of code sets up your controller response endpoint. Its address is also http://yourwebserverpath/api/shorturl/new
app.post('/api/shorturl/new' ...);

If you have the client set up like the code below, then the your page would call,
http://yourwebserver/index.html/api/shorturl/new. I don’t know if that is exactly what is happening, but that was why I suggested what I did.

<form action="api/shorturl/new" method="POST">

Your correct the forward slash should be on the client side and the server side.
I just found it odd that

<form action="api/shorturl/new" method="POST">
app.post('/api/shorturl/new' ...);

Did not cause an error for me because I didn’t catch the missing / . Usually if I miss one character I get errors. Like if the missing / is on the server side as

<form action="/api/shorturl/new" method="POST">
app.post('api/shorturl/new', (req, res) => {
res.send...);
}

Will result in an error, or perhaps not an error but the res will be undefined.