NextJS router.query not giving the ID param [duplicate] - mysql

This question already has answers here:
useRouter/withRouter receive undefined on query in first render
(9 answers)
Closed 3 months ago.
I am making crud using nextjs as frontend and CodeIgniter as backend I am following a tutorial where the frontend is reactjs. in reactJs when the updating part of the crud comes we can use the react-router-dom useParam function to get the ID but in nextJS we use router.query and it does not work so I am now stuck on how to get the id of the specific column to update it
const { id } = router.query;
const getProductById = async () => {
// if (id !== undefined && id != null && id > 0) {
const response = await axios.get(`http://localhost:8080/companies/${id}`);
setName(response.data.name);
setCreatedBy(response.data.createdBy);
console.log(id);
// }};
This is the code I am using and it gives an error that
`http://localhost:8080/companies/undefined`

You can get query.id on the server-side and then pass it to the client-side
export async function getServerSideProps(context) {
const { id } = context.query;
console.log(`query id: ${id}`);
return { props: { id } };
}
Now id is passed as prop to the client:
const YourComponent=(props)=>{
console.log("passed id prop",props.id)
}

Router query can be empty on the first render, on statically optimized pages.
try wrapping the code in useEffect
useEffect(()=>{
const { id } = router.query;
const updateProduct = async (e) => {
e.preventDefault();
await axios.patch(`http://localhost:8080/companies/${id}`, {
company_name: name,
created_by: createdBy,
});
router.push("/products");
};
},[router.query])

Related

Variable isn't getting updated [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 24 days ago.
I have this script. In the createApp function, I have a variant variable.
And you can see that I do a console.log(variant) below axios.get(). It logs 'ealjapd (it is the variant content).
But it is supposed to change to results.data.variants[0]. But it isn't changing... any suggestions?
<script>
if (document.querySelector('#add-to-cart-form')) {
const app = Vue.createApp({
delimiters: ['${', '}'],
setup() {
let variant = Vue.ref('ea´ljapd');
axios.get('/products/{{product.handle}}.js').then((results) => {
variant = Vue.ref(results.data.variants[0]);
console.log(variant);
});
const addToCart = (event) => {
event.preventDefault();
axios
.post('/cart/add.js', data)
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
};
return {
variant,
};
},
}).mount('#add-to-cart-form');
}
</script>
I can't figure it out, I need help
try this
variant.value = results.data.variants[0]
reference here
https://vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive-variables-with-ref

How to create childElement from server response in a react app

I created a react app with many nested routes.
One of my nested route is using a backend api that returns a complete HTML content.
And I need to display that exact content with same HTML and styling in my UI.
I'm able to successfully achieve it by manipulating the DOM according to axios response using createElement and appendChild inside useEffect method.
But, the whole philosophy behind using react is, to NOT modify the DOM and let react work on it by simly updating the states or props.
My question is:
Is there a cleaner way to use api returned HTML in a react app?
Here is sample relevant code:
Item.js
...
...
useEffect( ()=>{
const fetchAndUpdateItemContent = async () => {
try {
const response = await axios.get(url);
var contentDiv = document.createElement("div");
contentDiv.innerHTML = response.data.markup;
document.getElementById(‘itemContent’)
.appendChild(contentDiv);
} catch (err) {
.....
console.error(err);
......
}
}
};
fetchAndUpdateItemContent();
},[itemId])
return (
<div id=‘itemContent'/>
);
}
What did NOT work
Ideally I should be able to have a state as itemContent in Item.js and be able to update it based upon server response like this. But when I do something like below, whole HTML markup is displayed instead of just the displayable content.
const [itemContent, setItemContent] = useState(‘Loading ...');
...
useEffect( ()=>{
const fetchAndUpdateItemContent = async () => {
try {
const response = await axios.get(url);
setItemContent(response.data.markup)
} catch (err) {
.....
console.error(err);
......
}
}
};
fetchAndUpdateItemContent();
},[itemId])
return (
<div id=‘itemContent'>
{itemContent}
</div>
You're actually trying to convert an HTML string to a JSX. You can assign it into react component props called dangerouslySetInnerHTML
Eg:
const Item = () => {
const yourHtmlStringResponse = '<h1>Heading 1</h1><h2>Heading 2</h2>'
return <div dangerouslySetInnerHTML={{__html: yourHtmlStringResponse}}></div>
}
You can try it here dangerouslySetInnerHTML-Codesandbox
I believe you can use dangerouslySetInnerHTML

How can I loop through Nuxt.js generate routes to allow all my pages to render while using Woocommerce API?

Hello and thanks for the help in advance.
I'm trying to get my Nuxt app to automatically loop through my Woocommerce API automatically so it can generate the pages without much work.
How do I get the loop to function. Right now, I'm having issues and get a Nuxt Fatal Error:
TypeError: Cannot read property 'forEach' of undefined
Screenshot of Error + Code
I'm using Woocommerce API and, as you can see in the screenshot above, the Woocommerce code is imported into this code I need help with using a standard import.
import WooCommerce from './woocommerce.js';
generate: {
routes() {
WooCommerce.get("products").then((response) => {
let totalPages = response.headers['x-wp-totalpages'];
let page = 1;
while(page <= totalPages) {
WooCommerce.get("products", page).then((response) => {
response.data.map(product => {
return '/product/' + product.slug
});
})
page++;
}
})
}
},
You are not returning any routes in your routes function. Because of that, nuxt fails as it tries to iterate over them in a later step.
Assuming your way of accessing your API is correct, you would only need to add an array to which you push your routes and then return it.
I'm usually using async/await, which is why my code looks slightly different. It is a bit easier in this case I think.
// Declare the routes function asynchronous
async routes() {
const productsResponse = await WooCommerce.get('products');
const totalPages = productsResponse.headers['x-wp-totalpages'];
// Add an array to collect your routes
const routes = [];
let page = 1;
while (page <= totalPages) {
const pagesResponse = await WooCommerce.get('products', page);
// The 'map' function returns the routes for this set of pages
const productRoutes = pagesResponse.data.map((product) => {
return '/product/' + product.slug;
});
// Push your routes to the created array-
routes.push(...productRoutes);
page++;
}
// Return your routes
return routes;
};

TypeError: Converting circular structure to JSON for mongodb/mongoose

var express = require("express")
let PersonModel = require('./PersonModel')
let mongodbConnected=require('./MongodbConnect')
var app =express()
var bodyparser=require("body-parser")
const { format } = require("path")
const { count } = require("console")
const { countDocuments } = require("./PersonModel")
const { exec } = require("child_process")
const { get } = require("http")
const { ALL } = require("dns")
app.use(bodyparser.urlencoded({extended:false}))
app.get('/',function(req,res){
res.sendFile('Person.html', { root: __dirname });
})
app.get('/about',function (req,res){
res.send("This is a simple express application using mongodb express html and mongoose")
PersonModel.countDocuments().exec()
.then(count=>{
console.log("Total documents Count before addition :", count)
}) .catch(err => {
console.error(err)
})
})
app.post('/add', function(req,res){
Pname=req.body.empname
console.log('Pname',Pname)
PAge=req.body.Age
PGender=req.body.gender
PSalary=req.body.salary
const doc1 = new PersonModel(
{
name:Pname,age:33,Gender:PGender,Salary
:PSalary}
)
doc1.save(function(err,doc){
if (err) return console.error(err)
else
console.log("doc is added ",doc)
//res.send("Record is added"+doc)
res.send({
'status':true,
'Status_Code':200,
'requested at': req.localtime,
'requrl':req.url,
'request Method':req.method,
'RecordAdded':doc});
}
)
})
app.post('/findperson', function(req,res){
PAge=req.body.Age
console.log("Page",PAge)
PersonModel.find({age:{$gte:PAge}})
// find all users
.sort({Salary: 1}) // sort ascending by firstName
.select('name Salary age')// Name and salary only
.limit(10) // limit to 10 items
.exec() // execute the query
.then(docs => {
console.log("Retrieving records ",docs)
res.send(docs)
})
.catch(err => {
console.error(err)})
})
app.post('/delete', function(req,res){
Pgender=req.body.gender
PersonModel.findOneAndDelete({Gender:Pgender }
).exec()
.then(docs=>{
console.log("Deleted")
console.log(docs); // Success
}).catch(function(error){
console.log(error); // Failure
});
})
app.post('/update', function(req,res){
Pname=req.body.empname
Pnewname=req.body.newname
PnewAge=req.body.newage
PersonModel.findOneAndUpdate({ name: Pname },{"$set":{name:Pnewname,age:PnewAge}}).exec()
.then(docs=>{
console.log("Update for what i get is ",Pname
,Pnewname,PnewAge)
console.log(docs); // Success
}).catch(function(error){
console.log(error); // Failure
});
})
var docnum=PersonModel.countDocuments(ALL)
app.post('/count', function(req, res){
res.send('Total number of documents: ', docnum)
})
app.listen(5000,function(){
console.log("Server is running on the port 5000")
})
Hello.
First time posting on stackoverflow, dont know what kind of information to post, please let me know.
Im trying to make a page (/count) to simply display the number of documents. I've tried different code but nothing is working. This error keeps coming up "TypeError: Converting circular structure to JSON".
This is school work so the code is given to me by a teacher and I have to add a POST method to add a page that displays total number of documents.
Any ideas?
Thanks.
Circular structure is not about mongo but how JS read the JSON object.
For example, if you have this object:
var object = {
propA: "propA",
propB: object
}
When JS try to deserialize JSON object, will handle that: One object contains the object that contain again the object and again and again... that is a circular dependence.
Not only with one object itself, aslo with more objects:
var objectA = {
propA: objectB
}
var objectB = {
propA: objectA
}
Is the same case.
Using node.js you can use util.inspecet() which automatically show [Circular] when a circular dependence is found.
You can use like this:
var util = require('util')
console.log(util.inspect(objectA))

fetching data with react hook returns undefined on nested obj properties

Im trying to display data that has been fetched. but i cannot seem to display nested objects properties in react. Any ideas? if i log the data i first get a undefined, then the correct data.
my guess is that i need to wait for the data to be loaded then display it. but it does work for the title that is not in a nested obj.
function SingleBeneficiary({ match }) {
const [data, setData] = useState({ data: []});
const id = match.params.id
useEffect(() => {
async function fetchData() {
const response = await fetch(`http://localhost:8081/v1/beneficiary/${id}`);
const jsonData = await response.json()
setData(jsonData)
}
fetchData();
}, [])
return (
{data.title} // works
{data.address.careOf} // dont work
The data
{
"title":"myTitle",
"address":{
"careOf": "my adress"
}
}
Can you try like this?
I set initial data to null, and in return I check if it is not null.
If address can be null, additional null check is required.
function SingleBeneficiary({ match }) {
const [data, setData] = useState(null);
const id = match.params.id
useEffect(() => {
async function fetchData() {
const response = await fetch(`http://localhost:8081/v1/beneficiary/${id}`);
const jsonData = await response.json()
setData(jsonData)
}
fetchData();
}, [])
return (
<div>
{data && (
<div>
<p>data.title</p>
<p>data.address.careOf</p>
</div>
)}
</div>
);
}
You should check if address has careOf property before using it because first time data will be undefined and in second render it will have the data after the api call.
{data.address && data.address.careOf}
For anyone who is having a similar issue(i.e. fetching data via api and only the first time it runs, it will show the data as undefined but after manual refreshing, it works fine), here is a quick and sketchy addition you might consider alongside with 1. "Inline If with Logical && Operator" method and 2. using useState for checking if the api loading is over. With those three, mine worked.
Try fetching the desired data in the previous page of your app; in this case, add the following lines in any page you'll see before "SingleBeneficiary".
const response = await fetch(`http://localhost:8081/v1/beneficiary/${id}`);
const jsonData = await response.json()
Maybe it has to do with npm cache, but not really sure what's going on.
replace
return (
{data.title}
{data.address.careOf}
)
with
return (
{data?.title}
{data?.address?.careOf}
)