Issue with posting data from client-side to Express back-end route with Angular and BrowserSync

Having some difficulties with an Angular-Gulp-Browsersync-Express application while trying to use angular's $http resource to POST a simple "contact us" form to the express server.

Encountering this error every time I attempt to submit the form:

POST http://localhost:8080/submitContactUsForm 404 (Not Found)
Cannot POST /submitContactUsForm

Admittedly, my expertise lies more in front-end development than back-end, so it's possible that there is an issue with my server setup.

This is the configuration of my Express Server:

'use strict';
// Code for Express server... 

This is the Angular Controller responsible for the POST request:

(function() {
 'use strict';

angular
    .module('commonSenseDietApp')
    .controller('ContactController', ContactController);


 function ContactController($http, $log) {
    // controllerAs syntax
    var vm = this;

    // Function for processing contact form submission
    vm.processContactForm = function() {
        // Sending POST request using $http
    }
 }

})();

Here are the Client-Side Routes I have defined:

(function() {
 'use strict';

 angular
 .module('commonSenseDietApp')
 .config(routeConfig);

 function routeConfig($routeProvider) {
 // Route configurations...
}
})();

Contact form markup:

<section>
 <div class="contact-us-title">
    <h1>Contact Us</h1>
 </div>
 <!-- Form markup -->
</section>

Currently not seeing any logging in the terminal. Any assistance would be greatly appreciated.

Answer №1

Victory is mine!

After grappling with the challenges of getting Express to work harmoniously with browsersync, I finally stumbled upon the solution. Turns out, proxying browsersync to express and utilizing the gulp-nodemon package was the missing puzzle piece. With some restructuring, I've configured everything just right:

Here are my Browser-Sync server and gulp init tasks:

'use strict';

var path = require('path');
var port = process.env.PORT || 8080;
var gulp = require('gulp');
var conf = require('./conf');
var browserSync = require('browser-sync').create();
var browserSyncSpa = require('browser-sync-spa');
var util = require('util');
var proxyMiddleware = require('http-proxy-middleware');
var nodemon = require('gulp-nodemon');
var reload = browserSync.reload;

function browserSyncInit(baseDir, browser) {

 var routes = null;
 if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
  routes = {
   '/bower_components': 'bower_components'
  };
 }

 browserSync.instance = browserSync.init({
  startPath: '/',
  cors: true,
  browser: browser = browser === undefined ? 'default' : browser,
  proxy: 'http://localhost:8081',
  port: port
 // https: true
 });
}

browserSync.use(browserSyncSpa({
 selector: '[ng-app]' // Only needed for angular apps
}));

// Run Gulp tasks
gulp.task('serve', ['browser-sync','setenvconstants','watch']);

gulp.task('browser-sync', ['nodemon'], function () {
 browserSyncInit([path.join(conf.paths.tmp, '/serve'),   conf.paths.src]);
});
gulp.task('serve:dist', ['setenvconstants','build'], function () {
 browserSyncInit(conf.paths.dist);
});
gulp.task('serve:e2e', ['inject'], function () {
 browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
});
gulp.task('serve:e2e-dist', ['build'], function () {
 browserSyncInit(conf.paths.dist, []);
});
gulp.task('nodemon', [], function(done) {
 var running = false;

 return nodemon({
  script: 'api/app.js',
  watch: ['api/**/*.*', 'src/**/*.*']
 })
 .on('start',function() {
  if (!running) {
    done();
  }
  running = true;
 })
 .on('restart', function() {
  setTimeout(function(){
    reload();
  }, 500);
 });
});

Behold, my mighty Express server:

var express = require('express');
var bodyParser = require('body-parser');
var http = require('http');
var port = process.env.PORT || 8081;
var cors = require('cors');
var path = require('path');
var publicRoutes = require('./http/routes/web.js');

// require database data modeling via mongoose
var mongoose = require('mongoose');

// Express Session allows us to use Cookies to keep track of
// a user across multiple pages. We also need to be able to load
// those cookies using the cookie parser
var session = require('express-session');
var cookieParser = require('cookie-parser');

// Flash allows us to store quick one-time-use messages
// between views that are removed once they are used.
// Useful for error messages.
var flash = require('connect-flash');

// Use Express and set it up
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
// Parse requests to JSON
app.use(bodyParser.json({type: '*/*', limit: '50mb'}));
// set Jade as the view engine
app.set('view engine', 'jade');
// tell server where to find our views
app.set('views', __dirname + '/.././src/app/views');
// make sure bower components are installed.
app.use('/underscore',    express.static(path.resolve('.././node_modules/underscore')));
// tell our server where to find static assets depending on the environment.
process.env.NODE_ENV == 'production' ?  app.use(express.static(path.join(__dirname + '/../..'))) :  app.use(express.static(path.join(__dirname + '/.././dist')));
// enable cors
app.use(cors({
 "origin": "*",
 "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
 "allowedHeaders": ["Origin, X-Requested-With, Content-Type, Accept, Authorization"],
 "preflightContinue": false
}));

// Pull in our public routes
app.use('/api', publicRoutes);

// Listen
app.listen(port, function(error) {
 if (error) {
  console.error(error);
 } else {
  console.info("==> 🌎  Listening on port %s. Visit http://localhost:%s/ in your browser.", port, port);
 }
});

Now, I can confidently $http.post from my Angular controller given the route prefix in my express server:

vm.processContactForm = function() {

  return $http.post('/api/submitContactUsForm', vm.contactInfo)
      .then(returnSendSuccessful)
      .catch(sendFail);

  function returnSendSuccessful(response) {
    $log.log(response);
    // return response.data;
  }

  function sendFail(err) {
    return $log.error(err.data);
  }
}

The only obstacle remaining is...

process.env.NODE_ENV == 'production' ? app.use(express.static(path.join(__dirname + '/.././src'))) : app.use(express.static(path.join(__dirname + '/.././dist')));

While '/dist' loads perfectly well, '/src' only presents a blank index.html page on my localhost. I'll address this in a separate query and consider this conundrum conquered. Grateful for the assistance!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the Dependency Injection array in Angular directives

After some deliberation between using chaining or a variable to decide on which convention to follow, I made an interesting observation: //this works angular.module("myApp", []); angular.module('myApp', ['myApp.myD', 'myApp.myD1&a ...

Unleashing the power of RollupJs: A guide to dynamically bundling modules and objects

Is there a way to dynamically bundle a module/object into my RollupJs output file? I have experimented with various options without success in achieving the desired result. Below is a brief sample project that demonstrates what I am trying to achieve. The ...

Strategies for testing a split get() function using expressJS and jestJS to streamline unit testing

How can I define a get() route in an Express.js application for easy unit testing? To start, I extracted the get() function into its own file: index.js const express = require('express') const socketIo = require('socket.io') const Gp ...

Building Dynamic Columns within a react.js Environment

Can anyone help me with creating a dynamic column in react.js? I've already managed to do it with static columns, but now I want to make them dynamic. Take a look at my code below and please provide suggestions. import React from 'react'; i ...

Why does jQuery val() function fail to clear readonly input date in Firefox but succeed in Chrome?

When using JQuery.val(''), I noticed a difference in behavior between Firefox and Chrome. You can see the issue demonstrated in this jsfiddle: https://jsfiddle.net/mdqfbj/d4eovkg8/3/ A JS function triggered by a radio button is supposed to clea ...

Troubleshooting issue with jquery.i18n.properties functionality

I am encountering an issue with implementing jQuery internationalization. I have included the files jquery.i18n.properties.js, jquery.i18n.properties-min.js, and jquery-min.js in my resources folder. In my jsp, I have added the following code: <script ...

RSS feed showing null xml data with jQuery

Working on coding a straightforward RSS feed utilizing jquery and pulling data from Wired. Everything appears to be functioning correctly, except for one issue - after the description, an unknown value of NaN is appearing in the result. It seems to be comi ...

Is there a way to determine the dimensions of a pdf file using javascript and capture a snapshot of it for showcasing on a website?

I'm fairly new to HTML/CSS and haven't delved into javascript yet, but I have a good understanding of reading other people's code. Currently, I'm putting together my portfolio website and would like to include my resume on the page in a ...

Modal feature malfunctioning in web browser

My function is not working in the mobile browser, but it works on desktop. I'm not sure why this is happening. Has anyone experienced this before? $('body').on('click touchstart', '.show_range', function(event) { alert(" ...

Navigating the parent navController in Ionic 2: A step-by-step guide

I'm currently honing my skills in Ionic 2 by creating a basic app, but I've encountered an issue that has me stumped. The app features an ion-nav element for the login page, then transitions to a tabs navigator after successful login. The struct ...

Issue with Framer Motion Modal: Animation presence fails to function

Currently, I am facing an issue with the exit animation of a modal created using framer motion. While the initial animation on opening the modal works perfectly fine, the exit animation fails to trigger and the modal disappears abruptly without any transit ...

Numerous modals implemented within a React component

Currently, I am working on mapping different products, each with its own "report" button. The issue I am facing is that when I click on the "report" button for one product, all the other modals also pop up showing irrelevant details. It should only display ...

Running the command "npm start" will keep your application running indefinitely

Even when the status shows online, I am still unable to run the port on 8014. Whenever I try using pm2 to start tools/srcServer.js "scripts": { "prestart": "babel-node tools/startMessage.js", "start": "npm-run-all --parallel test:watch open:src", "ope ...

I am encountering a confusing issue where utilizing await does not actually wait for a Promise to resolve. Can you shed some light on why this unexpected behavior is happening?

Here is a function that I am working with: const getCurrentDetails= async () => { const currentDateTime = new Date(moment('00:00','HH:mm') .tz('America/New_York') ...

Jasmine test failing due to uninitialized angular controller

I encountered some difficulties while writing jasmine tests for an AngularJS application that utilizes angular ui-router. Despite proper initialization of my services and app in the test, I found that the controllers were not starting up correctly. In an e ...

Passing data from getServerSideProps to an external component in Next.js using typescript

In my Index.js page, I am using serverSideProps to fetch consumptions data from a mock JSON file and pass it to a component that utilizes DataGrid to display and allow users to modify the values. export const getServerSideProps: GetServerSideProps = async ...

Adding items to an array in Jade

I'm currently working on creating an array in Jade and then looping through another array to create a new one. My code looks like this: .metadata4 - var prepopulate = [] - if (entry.artist_ids) - for (var arti ...

Generating HTML content using JavaScript object data

I have a JavaScript file that holds data in the form of objects : let restaurant_A = { name: "BBQ place", min_order: 20, delivery_charge: 5, menu: { //First category "Appetizers": { //First it ...

What causes the "500: Unknown web method" error when JavaScript tries to call a Page WebMethod?

I am encountering an issue with a method in CreateTicket.aspx.cs: [WebMethod()] public static string Categories() { var business = new CategoryBusiness(); var categories = business.ListRootCategories(); return categories.Json(); } Additiona ...

Differences in scope variables between Angular 1 and Angular 2

When working with scope.$on, scope.$watch, scope.$broadcast, $scope.$apply, $scope.$emit, etc, in Angular 1, I found that these properties are not valid in Angular 2. Can anyone recommend alternative methods for achieving similar functionality in Angular ...