Nuxt3: Why cannot read properties of undefined (not sure if hydration error)? - nuxtjs3

I am trying to troubleshoot what I suspect might be a hydration issue (not sure).
First, when I run my Nuxt 3 app locally, I get the following server error:
[nuxt] [request error] Cannot read properties of undefined (reading 'public_id')
at _sfc_ssrRender (/C:/Users/XXX/Desktop/work/XXX/.nuxt/dist/server/server.mjs:36425:25)
The template code for the above error is referenced here:
/pages/post/[id]/index.vue:
<img
:src="
post.data.public_id //<----- the 'public_id' error referenced above
? config.public.cloudinaryBaseURL +
config.public.cloudinaryCloudName +
'/c_scale,f_auto,q_auto:best,w_900/' +
post.data.public_id
: '/images/placeholder.svg'
"
:alt="post.data.title"
class="img-fluid rounded-0 rounded-top"
style="border-top-right-radius: 0% !important"
/>
Commenting the above code out of the template, the error then jumps to the next line in the template code:
<figcaption class="figure-caption flex-grow me-auto">
{{ post.data.caption }} //<---- error jumps here after the above code commented out
</figcaption>
Locally, the above error is not a problem....the app works fine. Deploying to production, the page works but when you refresh the page, the error is a little different and the app's console says:
TypeError: Cannot read properties of null (reading 'data')
at Proxy.<anonymous> (index-fcf8af7d.mjs:1:11056)
at Ja (entry-52e152da.mjs:4:4370)
at $e (entry-52e152da.mjs:4:38329)
at $o.U [as fn] (entry-52e152da.mjs:4:38418)
at $o.run (entry-52e152da.mjs:1:4900)
at B.d.update (entry-52e152da.mjs:4:38728)
at B (entry-52e152da.mjs:4:38754)
at entry-52e152da.mjs:4:8797
Data is being fetched using server route api like so:
/pages/post/[id]/index.vue:
const { data: post } = await useFetch(`/api/posts/${route.params.id}`, {
initialCache: false
})
/server/api/posts/[id].ts:
import { firestore } from '#/server/utils/firebase'
export default defineEventHandler(async (event) => {
const postRef = firestore.doc(`posts/${event.context.params.id}`)
const snapshot = await postRef.get()
if (!snapshot.exists) {
return {
statusCode: 404,
body: JSON.stringify({
message: 'Post not found'
})
}
} else {
const data = snapshot.data()
return {
data
}
}
})
Does anyone have any advice on how I can fix the above error? Is there a better way to call the server route to alleviate this error?

Related

Handle 422 with $fetch

I'm upgrading a project to Nuxt3 and I'm using the new $fetch to hit my API, all it's OK but I can't manage the handle the 422 error from the API.
The API I've created would return something like this for the 422 code
{ message: "The email has already been taken.", errors: { email: ["The email has already been taken."]}}
Then in Nuxt I'm using this:
$fetch(`${runtimeConfig.public.BASE_API_BROWSER_URL}/XXX/`, {
method: 'POST',
body: {
...data
}
})
.then((resp) => {
message.value.push(resp.message)
isSubmitting.value = false
})
.catch((error) => {
errors.value.push(error.message)
isSubmitting.value = false
})
But what I have back is just FetchError: 422 Unprocessable Content instead of the error inside the API response, any idea on how to able to use error.message again?
Should be typically accessible via error.response.message.
For better visibility of the error object structure, use console.dir to explore its contents in the browser console: console.dir(error)
Unlike console.log(var1, var2, var3), console.dir only handles one attribute.
Important to remember this else you will be misled to thinking variables are empty.

Vue Firebase / Firestore Duplicates

I am trying to go through a tutorial (link below) to learn vue and firebase. There is a main dashboard page with a list of components, and I have gotten that to display a list of employees. Then there is a view employee component. When I started to build that, and just loaded data, I started getting this error:
Uncaught FirebaseError {code: "app/duplicate-app", message: "Firebase:
Firebase App named '[DEFAULT]' already exists (app/duplicate-app).",
name: "[DEFAULT]", stack: "[DEFAULT]: Firebase: Firebase App named
'[DEFAULT]…0)↵ at fn (http://localhost:8081/app.js:89:20)"}
The firebase code I added to view employee is as follows:
import db from "./firebaseInit.js";
export default {
name: "view-employee",
data() {
return {
employee_id: null,
name: null,
dept: null,
position: null
};
},
beforeRouteEnter(to, from, next) {
db
.collection("employees")
.where("employee_id", "==", to.params.employee_id),
get().then(querySnapShot => {
querySnapShot.forEach(doc => {
next(vm => {
vm.employee_id = doc.data().employee_id
vm.name = doc.data().name
vm.dept = doc.data().dept
vm.position = doc.data().position
})
});
});
}
};
When I comment out this script on the view employee page, the error goes away. From what I can tell, I have done everything the same as the tutorial in the video, and as my buddy who did the same project.
There is also a warning, which may be related, which states as follows:
There are multiple modules with names that only differ in casing. This
can lead to unexpected behavior when compiling on a filesystem with
other case-semantic. Use equal casing. Compare these module
identifiers: *
/Users/jdurell/code/employeemanager/node_modules/babel-loader/lib/index.js!/Users/jdurell/code/employeemanager/src/components/FirebaseInit.js
I am working on this tutorial / project:
https://www.youtube.com/watch?v=cjEzK4me1k8&index=4&list=PLillGF-RfqbYsOOycB67Raf9dwmL6Y31M
Nemesv had the correct answer. It was a casing issue. I had the issue FirebaseInit on the other component. I changed that to firebaseInit so it was the same case on both components, and the error resolved. Thanks!

Reset state of a Redux store causing incosistent selectors with React Router

I'm experiencing a number of issues trying to reset my state of Redux when changing routes.
On enter in routeA and click browser history to routeB, after firing ##router/LOCATION_CHANGE for routeB it performs the selectors of wrong routeA and causes various undefined state errors.
It should not run the routeA selector, as i'm getting into routeB and I believe this is the problem but I have no idea how to solve it.
In some even happened to be showing duplicate keys in the state, sometimes by the way I'm trying to reset the state wrong.
My scenery
In onEnter of the React Router i execute replaceReducers, see:
My routes onEnter callback:
function onEnter() {
replaceReducers({ book, dragAndDrop })
}
replaceReducers:
function replaceReducers(reducers) {
const appReducers = combineReducers({ ...reducers, ...defaultReducers })
store.replaceReducer((state, action) => {
if (action.type === 'RESET_STORE') {
const { routing, application } = state
state = { routing, application }
}
return appReducers(state, action)
})
store.dispatch({ type: 'RESET_STORE' })
apollo.setStore(store)
}
Steps I followed and what happened the error:
Enter routeA;
Go to routeB;
Click in browser history to routeA;
routeB is called incorrectly;
Error in console:
Uncaught TypeError: Cannot read property 'get' of undefined in routeB-selector.js
getItems: book => book.get('items')
This routeB selector can not be called and something has run it automatically.
Help me, please...

Error while instanciating Restivus "Cannot find name 'Restivus' "

I imported restivus using :
meteor add nimble:restivus
And while using Restivus I encounter this error on meteor startup :
"Cannot find name 'Restivus' ".
I can although GET requests but I wonder if it impacts the behavior of the app.
Here is the code used :
if (Meteor.isServer) {
// Global API configuration
var Api = new Restivus({
apiPath: 'api/',
prettyJson: true
});
}
When receiving POSTs my request.body and my bodyParams are empty :
Api.addRoute(':id/test', {
post: function () {
var id = this.urlParams.id;
console.log("Body contains : ");
console.log(this.bodyParams);
return {
status: 'success',
url : 'post test from id: '+id,
body : this.bodyParams
};
}
});
Does anyone know how to make this error disappear and if this is linked to the POST body problem ?
If you use Meteor 1.4+ you can try to import Restivus to your file with something like this:
import Restivus from 'nibmle:restivus';
The problem with post body being empty was caused by the request I made :
I wasn't specifying the Content-type header.
Once I specified the "Content-Type": "application/json" it worked.
The "Cannot find 'Restivus' " Error is still here though.
Your code looks ok. Here is some code from a server-only file that I am using:
// Global API configuration
var Api = new Restivus({
useDefaultAuth: true,
prettyJson: true,
apiPath: 'restAPI/',
defaultHeaders: { 'Content-Type': 'application/json;encoding="UTF-8"' }
});
// Generates: GET, POST on /api/items and GET, PUT, DELETE on
// /api/items/:id for the Items collection
Api.addCollection(Policy);
Perhaps you should move your code to the server directory? I am on Meteor 1.3.4.

Data context in Meteor's Template.rendered callback randomly disappears on hot code push

Short version:
Session.get(), and Template.currentData() that are supposed to be passed to the template by the Router often turn out to be undefined in Template.<templateName>.render callback. This happens quite randomly, most often on hot code pushes, but not always, and not only on hot code pushes.
Longer version:
I'm using Iron Router to pass data context to the template appBody:
Router.route('/:_mapid', function() {
if (!isNaN(this.params._mapid)) {
Session.set('currentMap',Maps.findOne({mapid: Number(this.params._mapid)}));
this.render('appBody', {
data: function() { return Session.get("currentMap") }
});
}
});
The template then uses d3 to generate a bunch of div's, and set the dynamic page title in Template.appBody.rendered callback:
Template.appBody.rendered = function() {
Deps.autorun(function() {
d3.select("#map_body").selectAll("div").remove();
d3.select("#map_body").selectAll("div")
.data(Nodes.find({mapid: Template.currentData().mapid }).fetch(), function(d) {return d.nodeparentid;})
.enter().append("div")
.attr("id", function(d){return "node"+ d.nodeparentid})
.style("position","absolute")
.style("top",function(d) {return d.toppos+"px"})
.style("left",function(d) {return d.leftpos+"px"})
.style("width",function(d) {return d.width+"px"})
.style("height",function(d) {return d.height+"px"})
.classed("node", true)
document.title = "Map - " + Session.get("currentMap").title;
}
As you can see I try to pass the data context to the template in two different ways: by setting a global currentMap object via Session.set and by passing data key via the Router, and then accessing it via Template.currentData() method.
For some reason both of these method often fail (although I still can't figure out under what conditions). Here is a sample error I get from the browser console when trying to set a document title:
Exception from Tracker afterFlush function: Cannot read property 'title' of undefined
TypeError: Cannot read property 'title' of undefined
at http://localhost:3000/client/templates/app_body.js?47b256634607ca16879aa0ed823593aec01ee840:122:31
at Tracker.Computation._compute (http://localhost:3000/packages/tracker.js?192a05cc46b867dadbe8bf90dd961f6f8fd1574f:288:36)
at new Tracker.Computation (http://localhost:3000/packages/tracker.js?192a05cc46b867dadbe8bf90dd961f6f8fd1574f:206:10)
at Object.Tracker.autorun (http://localhost:3000/packages/tracker.js?192a05cc46b867dadbe8bf90dd961f6f8fd1574f:476:11)
at Template.appBody.rendered (http://localhost:3000/client/templates/app_body.js?47b256634607ca16879aa0ed823593aec01ee840:117:10)
at null.<anonymous> (http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:2970:21)
at http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:1720:14
at Object.Blaze._withCurrentView (http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:2029:12)
at http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:1719:15
at Tracker.flush (http://localhost:3000/packages/tracker.js?192a05cc46b867dadbe8bf90dd961f6f8fd1574f:438:11)
Any ideas on what could be causing this?

Resources