Our server is setup as follows, using react, graphql, mongo and express:
public
index.html
service.js
src
assets
client (has 2 client side js files)
components (for react)
game.jsx
server (graphql server)
server.js
I need to register a service worker so that I can send push notification to players; the call is from game.jsx (the one that gets loaded when I want the serviceWorker to be registered):
const swreg = await navigator.serviceworker.register('service.js');
This causes a get request to ourURL.com/service.js (hence why I have service.js under public, as that's where it's served)
This is fine and dandy, but then I keep getting import errors in service.js:
Uncaught SyntaxError: Unexpected token {
this is the offending code in service.js:
import { saveSubscription } from "src/queries/queries";
Where saveSubscription is a graphql mutation call, and is defined in src/queries/queries.js.
I have tried other forms of importing, but they give me a syntax error of somekind. Googling told me that I need a type="module" tag, which obviously does not apply to this case.
How can I solve this problem? Thanks!
I fixed it... sort of.
I removed the import line, and instead used a fetch within the function.
fetch(url, {
method: "POST", // get can't have body
'Content-Type': 'application/graphql',
body: JSON.stringify({graphQLQuery})
});
Related
I'm completely new to Node and Spring Boot and am having a difficult time performing a fetch call in my Node.js app. The overall structure of the project is a React front-end with a Java/Spring Boot back-end and Gradle. I'm trying to create a service that automatically runs in the background that the user will never interact with or even know of its existence.
I'm using Google BigQuery for this task and am running some simple SQL queries using the Node.js client library that Google provides. My issue is that after pulling in my data from BigQuery, I want to take that information and perform a POST call using fetch. However, this requires a Java function to make use of this external service I'm trying to trigger with my POST call and when I try running node GetBigQuery.mjs in my terminal I get an error message:
TypeError: Failed to parse URL from /api/delayorders
[cause]: TypeError [ERR_INVALID_URL]: Invalid URL
input: '/api/delayorders', code: 'ERR_INVALID_URL'
I'm not using node-fetch, axios, or any external library to make the POST request as I'm running node 18.8.0 that comes built-in with fetch.
Three main files in total:
BigQuery.js
Includes boilerplate code copied and pasted from Google's documentation.
GetBigQuery.mjs
// There is more code above and below but it's not
// necessary in order to understand my question
value.forEach(element => {
fetch("/api/delayorders", {
method: "POST",
body: JSON.stringify({
"orderIds": element.OrderReferenceId,
"date": tomorrow,
"time": "12:00",
"minutesFromUTC": new Date().getTimezoneOffset(),
"buCode": element.StoreNo,
}),
headers: {
"Content-Type": "application/json",
}
}).then(response => {
console.log(response);
})
})
Delay.java
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
#Log4j2
#RestController
#AllArgsConstructor
#RequestMapping("api")
public class Delay {
#Getter
private final OrderDelayService orderDelayService;
#PostMapping("/delayorders")
#ResponseStatus(HttpStatus.OK)
public String delayOrders(#RequestBody OrderDelayDto orderDelayDto) throws Exception {
orderDelayService.delayOrders(orderDelayDto.getOrderIds(), orderDelayDto.getDate(), orderDelayDto.getTime(), orderDelayDto.getMinutesFromUTC(), orderDelayDto.getBuCode());
return "OK";
}
}
When you make an HTTP request in a browser, you can use a relative URL. The absolute URL will be computed using the URL of the HTML document as the base URL.
So if you had an HTML document at http://example.com/ and make an HTTP request to /foo then the request would go to http://example.com/foo.
When your code is running in Node.js, there is no HTML document. There is no base URL. There is no automatic conversion of a relative URL to an absolute one.
You need to use an absolute URL. (Or a mechanism that supports relative URLs and lets you specify the base URL).
I've got a really simple JSON flat file db setup that works when running locally but doesn't work once it's hosted on Netlify. I don't get any other error info besides a 500 error on the server. I get the error even if all I do is import the clusterDB object, so something is happening with the lowdb object. I've also tried using another json db library called StormDB and I get the same issue.
Return my API route with a static import of the json file (no db libraries) also works fine.
I'm new to Next.js and this seems related to maybe the SSR portion of things since the API routes run only on the server? Do I need to structure my files differently? Are these libraries not compatible? Lowdb says it works with Node, and everything works locally for me.
Here is my db init file (root/db/db.js)
import {Low, JSONFileSync} from 'lowdb'
// Cluster DB Setup
const adapter = new JSONFileSync('cluster-db.json')
const clusterDB = new Low(adapter)
// Initialize if empty
clusterDB.read()
clusterDB.data ||= { clusters: [] }
clusterDB.write()
export {clusterDB}
And my only API route (root/pages/api/clusters.js)
import {clusterDB} from '../../db/db'
export default async function handler(req, res) {
await clusterDB.read()
switch(req.method) {
case 'POST':
let newCluster = {severity: req.query.severity, comments: req.query.comments, date: req.query.date}
clusterDB.data.clusters.push(newCluster)
clusterDB.write()
res.status(200).json({status: "Success", cluster: newCluster})
break;
case 'GET':
if(clusterDB.data.clusters) {
res.status(200).json(clusterDB.data.clusters)
} else {
res.status(404).json({status: "404"})
}
break;
}
res.status(200).json({test: "yay"})
}
I've created a React JS app and added a fetch() event to a class but I'm unable to work out how to locate the file path as the resulting code leads to a 404 Not Found error in the console.
LoginForm.js:11 POST http://localhost:3000/api/user-login 404 (Not Found)
I am trying to locate user-login.js within /src/api/user-login.js
This is my folder structure:
https://monosnap.com/direct/DT5zykUaHOVz8YMJy9O96B762bOsvQ
Here is the relevant code within the class from LoginForm.js:
class LoginForm extends React.Component {
handleSubmit(event) {
var user = {
'clientname': 'client name here',
'email': 'client email here'
};
fetch('/api/user-login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
})
}
render() {
// Stuff that gets rendered
}
}
I have attempted every variation of /app/user-login that I can think of, including:
app/user-login
app/user-login.js
/app/user-login
/app/user-login.js
./app/user-login
./app/user-login.js
../app/user-login
../app/user-login.js
Could somebody please enlighten me on how I can link to this file? Sorry if this is a stupid question, I've only been learning React JS for a couple of days. Thanks for your help.
I hadn't set-up an API server which is why this was showing a 404 error. I had to use ExpressJS which means that any time my React app makes a request to something that’s not a static asset (not an image or CSS or index.html, basically), it will forward the request to the server.
I used the following tutorial to do this:
https://daveceddia.com/create-react-app-express-backend/
I'm fiddling around with service workers and want to use sw-toolbox which has a way to support express-style routing. However, when I import it with any version of these lines:
importScripts('node_modules/sw-toolbox/sw-toolbox.js');
importScripts('../node_modules/sw-toolbox/sw-toolbox.js');
importScripts('/node_modules/sw-toolbox/sw-toolbox.js');
I get the following error:
A bad HTTP response code (404) was received when fetching the script.
:3000/node_modules/sw-toolbox/sw-toolbox.js Failed to load resource: net::ERR_INVALID_RESPONSE
Here's my service worker code so far:
(global => {
'use strict';
//Load the sw-toolbox library
importScripts('node_modules/sw-toolbox/sw-toolbox.js');
//Ensure that our service worker takes control of the page asap
global.addEventListener('install', event => event.waitUntil(global.skipWaiting()));
global.addEventListener('activate', event => event.waitUntil(global.clients.claim()));
})(self);
What am I doing wrong?
I'm not sure if this is right, as I didn't find any reference to this in the tutorials on sw-toolbox online, but I found a workaround to get it to import.
Apparently service workers don't work like module.import, that is, relative to the calling code directory. So I added this script in my server:
//serve the sw-toolbox
server.get('/sw-toolbox.js', (req, res) => {
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('content-type', 'text/javascript');
let file = path.join(__dirname, 'node_modules', 'sw-toolbox', 'sw-toolbox.js');
res.sendFile(file);
});
And call it from the service worker thusly:
importScripts('/sw-toolbox.js');
Can anyone explain to me why this works and importScripts doesn't?
I have been investing some time learning React, MongoDB, and other JS web app related tools. For a small project that I created, I am using this repository to create my toy app Create React App with no build. As I've progressed through my app I've learned a lot of React related tools and materials after the fact.
The part that I am stuck on is I am trying to submit a contact form's data into MongoDB but so far I'm unsuccessful in hooking up my app with MongoDB.
Here is my code for MongoDB. I've pretty much copy and pasted the code from the MongoDB guides onto my web app into a src/modules/mongo.js file
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const ObjectId = require('mongodb').ObjectID;
const url = 'mongodb://localhost:27017/danielrubio';
const insertFormData(db, callback) {
db.collection('contactsubmissions').insertOne( {
"name": name,
"message": message,
"email": email
}, function(err, result) {
assert.equal(err, null);
console.log("Inserted a document into the restaurants collection.");
callback();
});
};
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
insertDocument(db, function() {
db.close();
});
})
The above code is straightforward, it basically inserts one document into a collection.
Here is my second file in src/modules/contact.js
import React, { Component } from 'react';
import Formsy from 'formsy-react';
import { FormsyText } from 'formsy-material-ui/lib';
import Paper from 'material-ui/Paper';
import RaisedButton from 'material-ui/RaisedButton';
import Snackbar from 'material-ui/Snackbar';
import '../assets/css/style.css';
class ContactForm extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = { open: false };
}
handleSubmit(data) {
db.insertDocument({
form submission info
db.close()
})
}
......more code.....
}
Now so far, I've been able to work through the MongoDB guides, I've created my database, can access the console, and can insert data through the console. What I haven't figured out is how to wire my app to mongodb so when I click a submit button it will insert the document in the right database. Coming from Rails and using a little bit of Flask, I can usually call a .create method which connects to my database or do some sort of SQL Alchemy operation which opens and closes the database. I've tried this approach by attempting to combine the two files together but when I do that, I can't even run npm start otherwise I get these types of errors:
Error in ./~/mongodb/lib/gridfs/grid_store.js
Module not found: Error: Cannot resolve module 'fs' in /Users/drubio/Desktop/react_personal_website/node_modules/mongodb/lib/gridfs
# ./~/mongodb/lib/gridfs/grid_store.js 42:7-20
Error in ./~/mongodb-core/lib/connection/connection.js
Module not found: Error: Cannot resolve module 'net' in /Users/drubio/Desktop/react_personal_website/node_modules/mongodb-core/lib/connection
# ./~/mongodb-core/lib/connection/connection.js 5:10-24
Error in ./~/mongodb-core/lib/connection/connection.js
Module not found: Error: Cannot resolve module 'tls' in /Users/drubio/Desktop/react_personal_website/node_modules/mongodb-core/lib/connection
# ./~/mongodb-core/lib/connection/connection.js 6:10-24
So my question is how can I simply connect my app to open the mongodb database and write to it? I've been reading a lot of tutorials but then I get rabbit holed and confused further talking about Express, Mongoose, Flux and on and on. From a high level overview it seems like I don't even need Express or Mongoose, I simply just want to insert my data without a schema and to be honest I don't really get what Flux is but from what I gather, I don't really need it for my small app (I think). I could use a little nudge in the right direction on this one. Thanks.
[1]: https://github.com/facebookincubator/create-react-app
You have to create endpoint (server side) can be Node can be something else like php, and there you will accept request and insert the data to your database. Your React app will make ajax call to the server and the server will put the data to the database
If you want to do that with express you can create simple express app with one route that will get the data from the client and will send that to MongoDB. you dont have to use Mongoose you can use MongoDB driver or outer to simply send the data to MongoDB.