Unable to display information from fetched serialized api in react component - javascript

I am developing a web app that fetches concerts from an api based on a user search. However, since I want to add, and save, attributes from different users to those concerts, I decided that when a user clicks a link for an individual concert it a) gets saved to the database, and then b) renders the individual card component for that concert. However, the data rendered in the individual card is not the data from the external api, but data fetched from my own db, as to populate the extra attributes that my users have entered. That already has been a pain in and of itself. Now- here's the issue: For some reason whenever I try and display data from my redux state that's two levels deep, let's say like concerts.attributes.venue, I get a TypeError: Cannot read property 'venue' of undefined. This happens for any nested properties I have. For more context, I am using hooks to fetch the data from my db in my functional concert component. I also tried turning it into a class component with lifecycle methods, but same issue. Part of of me thinks it is the asynchronous nature of fetching, with data rendering before the entire serialized data comes back? I am not sure. Anybody know how to rectify this?

Share the code snippet for better understanding. its a bit difficult to just visualize the code by just your words.
you will get a some data as a response from the Api. You need to store that data to some variable. somewhat like this
XHR call in JS and storing response to var x
let x;
function successListener() {
var data = JSON.parse(this.responseText); //to parse the data to json format
x=data;
}
function failureListener(err) {
console.log('Request failed', err);
}
var request = new XMLHttpRequest();
request.onload = successListener;
request.onerror = failureListener;
request.open('get', 'URL', true);
request.send();
then access the data you need like this:
x[key][subkey]
don't know what you are doing here
concerts.attributes.venue

Related

What is the recommended way to write then read data in my firebase app?

I was wondering the best way to write then read data in my firebase app?
I currently make a post request and use set to set some data at a new location. the user does this via a modal
I then close the modal and want the user to see the updated content below (without a page refresh) is there anyway to use the completion callback to send back the new data?
should I make an api request again straight after?
or should I handle this client side?
so far I had this:
firebaseApp
.database()
.ref(`users/${userID}/${endpoint}`)
.set(setSchema, (error) => {
if(error){
consolse.log('error')
} else {
console.log('success')
}
})
is there anywhere on the success line we can return data?
thanks
Is there anyway to use the completion callback to send back the new
data?
No, the set() method does not return the value that is written at the Realtime Database node.
Should I make an api request again straight after?
It depends, see the next question.
Or should I handle this client side?
Normally you should be able to handle that in the client since you know what value (Object) you have passed to the set() method.
The only case when this is not true is when you use a sentinel (placeholder) value through firebase.database.ServerValue.
For example is you have a property startedAt: firebase.database.ServerValue.TIMESTAMP in the object you pass to the set() method, the exact value for startedAt will be calculated by the server, therefore you don't know it in advance. If you want to get this value, you need to query the database for it.

Save data from GET request as variable

I've got a simple axios GET request that is working with Azure directline 3.0. The GET request pulls back data and shows it in the console (as seen in the picture).
The data I want to save into a variable is the conversationId. I then want to use this variable with Axios Post in another JS file to post as part of the link e.g. let URL = "https://directline.botframework.com/v3/directline/conversations/"+convID"/activities". With convID being the variable I wish to create. Right now I am manually changing the convID with the new conversation ID, but I want to create a variable so I can place it in the post javascript file so it is automatic.enter image description here
There are various ways you can solve this problem. Easiest one being, exposing the data on a shared object window.convID = convID and then accessing it wherever required.
You could also look to make singleton objects, which can be instantiated only once and hence will share it's variables across the lifespan of the application.
axios.get(/* URL */).then(res => {
window.convID = res.data.conversationId;
});
You can save that variable value in LocalStorage. Something like this:
let routeToYourApi = '/api/conversations'; // or something like this...
axios.get(routeToYourApi).then((response) => {
let conversationId = response.data.conversationId; // not sure if data object from your image is directly nested inside response that you get from server, but you get the idea...
window.localStorage.setItem("convId", conversationId);
}) // here you can fetch your conversation id
Than you can access it anywhere in your app:
let conversationId = window.localStorage.getItem("convId");
... and eventually remove it from local storage:
window.localStorage.removeItem("convId")
Hope this will help you!

How to know if value changed in Parse Cloud Code afterSave hook?

I want to send push notifications every time the value of a single key of my object changes in a parse cloud code afterSave hook.
Parse.Cloud.afterSave("Channel", function(request) {
var channel = request.object
// TODO: check if value of channel key "state" was changed
});
How can I check if the value of the key state was updated?
This is all data I can get from the request object: http://parseplatform.org/Parse-SDK-JS/api/v1.11.0/Parse.Cloud.html#.TriggerRequest
The solution suggested in this thread feels wrong: Parse Javascript API Cloud Code afterSave with access to beforeSave values
I know I can do this via the dirty method in the beforeSave hook. However this does not work for me. Why? If I do send push notifications to many users this takes some time. The clients receiving the push notifications start requesting the updated channel object from the server. However they might receive an old version of the object because as long as beforeSave has not finished sending all pushes the channel object is not persisted in the database.
You can use request.original. For example:
Parse.Cloud.afterSave("Channel", function(request) {
var channel = request.object;
var channel_orig = request.original;
if (channel.get("status") != channel_orig.get("status")) {
// Send push notification.
}
});
The documentation states about request.original, that: "If set, the object, as currently stored." I'm not sure in what cases it would be set, though. In my use cases it works as provided in the code snippet above.

Creating an effective loop to gather data from an API for each item

What I'm trying to achieve is an effective way of passing each item found in a specific attribute through a JSON request in jQuery, so that I can gather information about it from an API. The API is Twitch and each data attribute is a streamers name.
Each streamer would be defined like so -
<div streamer='streamer_name'></div>
and from the API I'd like to gather their status and information. However, the Twitch API does not showcase information about offline streamers in the original API url, and so I have to use two API URL's to get all the required data.
I have created something that works, and as I'm rather new to this, I've most likely missed out on important features required to make this as effective as possible.
$('[streamer]').each(function() {
var data = $(this);
var streamer = $(data).attr('streamer');
$.getJSON('https://api.twitch.tv/kraken/streams/' + streamer, function(x) {
if (x.stream != null) {
$(data).append(
//online data
);
} else {
$.getJSON('https://api.twitch.tv/kraken/channels/' + streamer, function(x) {
$(data).append(
//offline data
);
});
}
})
})
http://jsfiddle.net/W4Km8/8801/ for an example of what this code actually does.
EDIT: There is also a way to search for multiple streamers at once, although again, it does not show any data for those that are offline.
https://api.twitch.tv/kraken/streams?channel=riotgames,scrags
EDIT2: To be more specific about my doubts, occasionally it will append the data incorrectly and will break the page layout, or not show up at all. This happens quite frequently upon page refreshes.
Thanks

Why is node.js variable persisting

I'm making a temporary fake API and am trying to set up a simple request response script in node using express.js to achieve this. It's very strraightforward, A request comes in, is validated and, if valid, is merged with a .json template file and the result returned, thus giving the impression the user was successfully created.
app.post('/agent/user', function(req, res){
var responseTemplate = new jsonRequired('post_user');
var errorTemplate = new jsonRequired('post_user_error');
var payload = req.body;
var responseData;
var hasErrors = false;
console.log('Creating new user');
//Recursive Merge from http://stackoverflow.com/a/383245/284695
responseData = new mergeRecursive(responseTemplate,payload);
if(!payload.username){
hasErrors = true;
errorTemplate.errors.username.push('A username is required.');
}
if (hasErrors){
res.send(errorTemplate,422);
}else{
res.send(responseData,200);
}
});
The problem I'm having is that data is persisting between calls. So if I define a username and name[first] in 1 request and just a username in the 2nd one, both requests come back with the name[first] property.
I have a feeling it's something to do with js closures. Unfortunately, every tutorial I find seems to be about making closures, not avoiding them.
It should work like this:
The client POST's username=user1&name[first]=joe&name[last]=bloggs
The Server loads a json file containing a prepopulated user object: e.g.
{"username":"demo","name":{"first":"John","last":"Doe"}...}
mergeRecursive() merges the payload from the POST request over the template object and returns the new object as the POST response text.
The problem is that with every new request, the server is using the result of step 3 in step 2 instead of reloading the .json file.
That mergeRecursive function has the same caveat as jQuery.extend: it modifies the first object sent into it. In fact, you don't even need to use its return value.
You didn't show the code of jsonRequired function (it's not even clear why you've used new when invoking it), but it looks like this function doesn't create a new object each time it's called, instead fetching this object from some outer repository. Obviously, mergeRecursive modifications for it won't be lost after that function ends.
The solution is using your data object for merging. Like this:
var responseData = {};
...
mergeRecursive(responseData, responseTemplate);
mergeRecursive(responseData, payload);
Merging two objects will make this for you.
If your responseTemplate has parameter, which actual request did not have, then you will end up having it there.
Check definition of word merge ;)
While this doesn't resolve the issue I had, I have found a workaround using the cloneextend package available via npm:
$ npm install cloneextend
This allows me to use the following js:
var ce = require('cloneextend');
...
ce.extend(responseData, responseTemplate);
ce.extend(responseData, payload);

Categories