I have a simple cloud function like so:
exports.sendReactionNotification = functions.https.onRequest(async (req, res) => {
console.log("received reaction");
functions.logger.log(req.body);
console.log(req.body["jsonPayload"]);
return;
});
But the above logs "undefined" in the google cloud console. I have also tried dot notation like so: req.body.jsonPayload. But I get this error instead: TypeError: Cannot read properties of undefined (reading 'reaction')
The webhook I am receiving the api call from sends a reaction, so that is where the "reaction" in the above error message comes from. I am tearing at my hair because this is mean to be simple, but I can't tell what the issue is.
This is what the JSON object looks like (the result of the functions.logger.log(req.body) above:
Instead of using jsonPayload, try logging reaction instead. I think jsonPayload is the JSON that is supplied to the logger function.
Related
I'm a newbie on mobile development and React-Native, this might come across as a very mundane thing to some of you, but I'm making an Api call and then mapping the results to create the same component but with different data.
This works fine on Iphone but on Android it does not.
The response from the req is an Object for both devices but on Android, it seems to be a json object that I simply cannot map with or use on a Flatlist.
I've tried JSON.parse to get the json object to a js object but it simply doesn't, like it. It throws out an unexpected token error.
I've attached a log for the Android object first and the same object for iPhone (Already mappable and a JS object).
Can someone tell me why this happens? I'd very much appreciate it!
enter image description here
____________________ After Changing to Fetch _______________________
Hey, I changed from Axios to fetch and now I get an unhandled promise warning saying 'Unhandled promise rejection: SyntaxError: JSON Parse error: Unrecognized token '' '.
Don't think I'm doing anything wrong here...
Well ... your response-object gets truncated due to memory issues on your real-device ... most likely your response object is kinda large ...
And that's just the way axios fetch response-data ... through chunks, you just get a slice of the response...
I came across this issue before ... and the solution was to switch to fetch
Edit
try {
const rawResponse = await fetch(...);
const text = await rawResponse.text();
console.log(text);
const parsedRes = JSON.parse(text);
console.log('parsedRes', parsedRes);
} catch(error) {
console.log('fetch error', error);
}
I am receiving the following error when I call inside getStaticProps and I cannot figure out why:
Error: Error serializing `.lingo` returned from `getStaticProps` in "/".
Reason: `undefined` cannot be serialized as JSON.
I've placed the full app code on CodeSandbox. It won't be able to access the API but it does show where things are defined.
When I run the following query on GraphQL playground I get the expected response:
query {
allTerms {
id
term
slug
lead
}
}
You can see that this query is contained in lingo.service.js in the modules/lingo/services directory on the sandbox but the homepage has the Error serializing error. Is my function export async function getAll() not correct or am I calling it wrong in getStaticProps?
await getAll() is most likely returning undefined which is not serializable JSON. Defaulting to null would be one way to solve the issue.
export async function getStaticProps(context) {
return {
props: { lingo: (await getAll()) ?? null },
};
}
Right, this is supposed to be more of a comment but apparently I don't have enough reputation points to comment. So, I'll answer it like this.
Just check if your props (under getStaticProps()) are named correctly i.e. how they're named in the .json file you're trying to read. I ran into this issue because of a typo I had and just fixed it.
I was using OMDBapi to get the details of different movies. I successfully fetched the result and it returns a json object like this;
{"Title":"WWA: The Inception","Year":"2001","Rated":"N/A","Released":"26 Oct 2001","Runtime":"N/A","Genre":"Action, Sport","Director":"N/A","Writer":"Jeremy Borash","Actors":"Bret Hart, Jeff Jarrett, Brian James, David Heath","Plot":"N/A","Language":"English","Country":"Australia","Awards":"N/A","Poster":"https://m.media-amazon.com/images/M/MV5BNTEyNGJjMTMtZjZhZC00ODFkLWIyYzktN2JjMTcwMmY5MDJlXkEyXkFqcGdeQXVyNDkwMzY5NjQ#._V1_SX300.jpg","Ratings":[{"Source":"Internet Movie Database","Value":"6.0/10"}],"Metascore":"N/A","imdbRating":"6.0","imdbVotes":"22","imdbID":"tt0311992","Type":"movie","DVD":"N/A","BoxOffice":"N/A","Production":"N/A","Website":"N/A","Response":"True"}
Note that we get this type of object from the api if we want to get a particular movie details and that is what i was doing. Now to show the different details to a user, i started parsing this JSON object which works fine but when i try to get the value of the Value key present inside the Ratings key, it returns undefined.
I am working with react-native. After getting the data, i stored it inside the state, named it as details. Then to get it;
this.state.details.Title //if i wanted to get the Title and it works fine.
Then for Value inside Ratings;
this.state.details.Ratings[0].Value
But it returns undefined.
Also note that this works fine in pure Javascript as i parsed the dict in the browser console in the same way and it returned the correct value.
Here is more code;
componentDidMount() {
this.fetchData();
}
fetchData = async () => {
const response = await fetch(`http://www.omdbapi.com/?i=${this.props.navigation.getParam('i')}&apikey=******`) // where this.props.navigation.getParam('i') is the omdbid of the movie
const result = await response.json()
this.setState({details: result})
}
Here is error log;
undefined is not an object (evaluating 'this.state.details.Ratings[0]')
You're most likely trying to access state object before fetch has done it's job .... it's an async op ... so you should make sure your data is ready before rendering...
if (this.state.details) {
// start rendering...
}
More Explanation
your setState function should be executed right after fetch has finished its job, and since it's an async operation, it's going to take some time ...During that time, render function is executed with no state.details --> causing your issue ...
That's why you should check for state before rendering ... besides, the optional chaining trick Silversky Technology mentioned in his answer
If the value property you are accessing from the object might be not available for all the movies in the data you are getting from API response so it might cause you to error when accessing key from undefined objects.
To overcome the issue there is a way, you can try a fix as below:
this.state.details.Ratings[0]?.Value
The ? symbol lets the javascript not give an error when the value key not available in the object. it will make the accessing of property optional.
When storing objects in states it often causes problems as you are doing in line
this.setState({details: result})
Save result after strigifying it like
JSON.stringify(result)
this.setState({details: result})
Then when fetching form state, parse it back to object by
var result = JSON.parse(this.state.details)
Then you should be able to access it
You can access Ratings[0].Value by
this.state.details.Ratings && this.state.details.Ratings[0].Value
like,
<Text> {this.state.details.Ratings && this.state.details.Ratings[0].Value} </Text>
TLDR: After writing a JSON (successfully) to my Firestore, the next request will give me Internal Server Error (500). I have a suspicion that the problem is that inserting is not yet complete.
So basically, I have this code:
const jsonToDb = express();
exports.jsondb = functions.region('europe-west1').https.onRequest(jsonToDb);
jsonToDb.post('', (req, res) => {
let doc;
try {
doc = JSON.parse(req.body);
} catch(error) {
res.status(400).send(error.toString()).end();
return;
}
myDbFuncs.saveMyDoc(doc);
res.status(201).send("OK").end();
}
The database functions are in another JS file.
module.exports.saveMyDoc = function (myDoc) {
let newDoc = db.collection('insertedDocs').doc(new Date().toISOString());
newDoc.set(myDoc).then().catch();
return;
};
So I have several theories, maybe one of them is not wrong, but please help me with this. (Also if I made some mistakes in this little snippet, just tell me.)
Reproduction:
I send the first request => everything is OK, Json in the database.
I send a second request after the first request give me OK status => it does not do anything for a few secs, then 500: Internal Server Error.
Logs: Function execution took 4345 ms, finished with status: 'connection error'.
I just don't understand. Let's imagine I'm using this as an API, several requests simultaneously. Can't it handle? (I suppose it can handle, just I do something stupid.) Deliberately, I'm sending the second request after the first has finished and this occurs.
Should I make the saveMyDoc async?
saveMyDoc isn't returning a promise that resolves when all the async work is complete. If you lose track of a promise, Cloud Functions will shut down the work and clean up before the work is complete, making it look like it simply doesn't work. You should only send a response from an HTTP type function after all the work is fully complete.
Minimally, it should look more like this:
module.exports.saveMyDoc = function (myDoc) {
let newDoc = db.collection('insertedDocs').doc(new Date().toISOString());
return newDoc.set(myDoc);
};
Then you would use the promise in your main function:
myDbFuncs.saveMyDoc(doc).then(() => {
res.status(201).send("OK").end();
}
See how the response is only sent after the data is saved.
Read more about async programming in Cloud Functions in the documentation. Also watch this video series that talks about working with promises in Cloud Functions.
I am new to Angular and I am trying to build a simple todo application using it. I have designed a module called TodoServices in which I am creating a User service using the factory method. The code looks something like:
angular.module('TodoServices', ["ngResource"])
.factory('User', function($resource){
return $resource('http://todoapi.rohanchhabra.in/users/:id');
});
The code in my app.js looks like:
var angularApp = angular.module('angularApp', ['TodoServices']);
angularApp.controller('UsersController', function(User){
this.users = {};
this.users = User.query();
});
When I run my application, I get this error: Error link
I think this is because my web service is returning an object which not only has the data but also has a few other things such as a status and messages. Now Is it a wrong way of doing it? Should I just return the array from the back end? What is the actual problem here and how to solve this?
As your error link says:
By default, all resource actions expect objects, except query which expects arrays.
You should use an other function like User.Get() when you're not expecting an array but just a single object.