react display property with number - reactjs

In reactjs I want to display a property.
Normally this isn't really hard to do it, but this time there is a number in the property. And that number depends on how many links the user has added.
This is an example of what my api returns to my react app:
embed_links: ["2"]
embed_links_0_embed_link: ["https://www.url.com"]
embed_links_1_embed_link: ["https://www.url.com"]
The embed_links is an array which says how many urls the user has filled in.
Then you get the urls the user has filled in, and each one has a number in it.
This is where I got stuck. I have tried to display the links with a for loop like this:
let embed_links = this.props.embed_links[0]
for (let i = 0; i < embed_links; i++) {
console.log(this.props.embed_links_[i]_embed_link[0]);
}
But this does not work..
So my question is basically, is there a possibility that you can display properties witch custom variables/numbers in it?

If you are asking access to a dynamical property within your object:
console.log(this.props["embed_links_" + i + "_embed_link"][0]);

Your syntax is wrong, the correct way to write this is as follows:
let embed_links = this.props.embed_links[0]
for (let i = 0; i < embed_links; i++) {
console.log(this.props['embed_links_' + i + '_embed_link][0]);
}
In the example, 'embed_links_' + i + '_embed_link' is the key that you use to select the correct property of object props.

Yes you can use this.props['embed_links_' + i + '_embed_link'][0]
However i would suggest storing your embed links in an array as objects
embed_links_collection: [
{
url:'https://www.url.com',
id: '1'
}
]
This is a cleaner, managable solution - you could also generate your embed_links property as this.props.embed_links_collection.length

You can use for .. in for enumerating this.props properties

Related

SOQL Query for getting the Application name of a Particular Tab

I would like to get the Application name of a specific sObject. For example: I have a custom object called Candidate__c. How to get the Application name of Candidate__c programmatically?
I am open to any approach like using Schema Namespace as well.
I am answering my question. I used Schema.describeTabs() and It works perfectly, but the Doc says the DescribeTabs method returns the minimum required metadata that can be used to render apps ...
Basically, The All Tabs are not included in the list of described tabs. The results are dependent upon the apps that are available to the running user.
// Get tab set describes for each app
List<Schema.DescribeTabSetResult> allApps = Schema.describeTabs();
// Iterate through each tab set describe for each app
for (Schema.DescribeTabSetResult oneApp : allApps) {
System.debug('The tabs/objects associated with the' + oneApp.getLabel() + ' app are:');
List<Schema.DescribeTabResult> appTabs = oneApp.getTabs();
for (Integer i = 0; i < appTabs.size(); i++) {
System.debug((i + 1) + '. Tab Name: ' + appTabs[i].getLabel());
}
}

can't manipulate JSON obtained through multiple $http.get and $q

I am trying to merge two jsons into one but can't make it work. I manage to retrieve the data I need from both get, but I have troubles manipulating the jsons.
I planned on using two for loops but it doesn't work :
$scope.coursesJson = $http.get('https://api.myjson.com/bins/18zi3');
$scope.reviewsJson = $http.get('https://api.myjson.com/bins/52toz');
$q.all([$scope.coursesJson, $scope.reviewsJson]).then(function (values){
$scope.coursesJson = values[0];
$scope.reviewsJson = values[1];
for(i = 0;i<$scope.coursesJson.length;i++){
for(j = 0;j<$scope.reviewsJson.length;j++){
if($scope.coursesJson[i].name = $scope.reviewsJson[j].name){
$scope.coursesJson[i].reviews.push($scope.reviewsJson[j]);
}
}
}
console.log($scope.coursesJson);
});
Using the console, I can visualise the data but $scope.coursesJson.length is undefined and I don't understand why.
Maybe I don't understand $q well ?
EDIT :
Here is an example of the elements you could find in the coursesJson file I get() :
[{"code":"123 ","name":"Acteurs","courseContentGrade":null,"courseTeachingGrade":null,"courseAverage":null,"reviews":null},
{"code":"1234","name":"Advanced Excel","courseContentGrade":null,"courseTeachingGrade":null,"courseAverage":null,"reviews":null}]
And an example of the elements you could find in the reviewsJson file I get() :
[{"code":"123 ","name":"Acteurs","professor":"Lalala","contentReview":"C'est très réussi.","teachingReview":"charismatique","contentGrade":8,"teachingGrade":8,"average":8,"trimester":"T2","day":"Jeudi / Thursday","time":"9h-12h","round":"1er tour","bet":21,"year":"2014/2015","upvotes":"0","author":"Piranha","passed":null},
{"code":"123 ","name":"Acteurs","professor":"LAlalalala","contentReview":"Très intéressant !","teachingReview":"Disponible, claire.","contentGrade":8,"teachingGrade":8,"average":8,"trimester":"T2","day":"Jeudi / Thursday","time":"9h-12h","round":"1er tour","bet":25,"year":"2014/2015","upvotes":"0","author":"Piranha","passed":null}]
I would like to add the elements found in the reviewsJson to the reviews field of the elements of coursesJson. Could that be the problem ? I thought that using the push() method would create the array, but maybe I need to change all "reviews":null to "reviews":[] in coursesJson ?
I went to the url https://api.myjson.com/bins/ID1 and it's not an array, but an object. Instead of $scope.coursesJson.length I think you shouldbe doing $scope.coursesJson.tracks.length
I solved my issue really easyly and my question was actually pretty stupid.
What I tried to achieve didn't have its place on the front but on the backend.

Using a loop to assign labels won't work in Actionscript 3. TypeError: Error #1010

I've used this website for many things and found a lot of useful information that has helped me create a randomized quiz mostly. I'm trying to make the code as efficient as possible and that has led me to this error.
I have created an array which uses the .push function to store existing buttons on the stage into the array for future use. The code shown below sets the label of each button correctly.
_buttons[0].label = xmlData.difficulty1.questions[num2].op1.text();
_buttons[1].label = xmlData.difficulty1.questions[num2].op2.text();
_buttons[2].label = xmlData.difficulty1.questions[num2].op3.text();
_buttons[3].label = xmlData.difficulty1.questions[num2].op4.text();
So naturally I wanted to make this a little more efficient and put these in a loop. Based on the logic this SHOULD work but doesn't.
for (var i:Number = 0; i < 4; i++)
{
_buttons[i].label = xmlData.difficulty1.questions[num2].op[i+1].text();
}
This code should simply increment the array counter of _buttons and set the label for each. I mean it's simply the first set of code in a for loop right? However when I run it I get the following error: TypeError: Error #1010: A term is undefined and has no properties.
Now I know for sure that the first set of code works as I have tested it repeatedly but as soon as I decide to put it into that for loop, it fails. Could anyone explain why? Perhaps it's a limitation of the language itself? Maybe I'm missing a command?
Try :
for (var i:Number = 0; i < 4; i++)
{
_buttons[i].label = xmlData.difficulty1.questions[num2]['op'+(i+1)].text();
}
.op[i+1] tries to access a property called 1 under a field called op instead of op1

Declaring new variables on the fly?

Has anyone found a way to declare variables on the fly?
I have some variables that can be limitless...
val1
val2
val3
val4...
Is there a way to create these on the fly, something like...
for(loop though){
val + '1' = dosomething('1')
}
I know it wont look anything like the above, but hoping you get the gist of it.
Apex is a compiled, not parsed / dynamic language. You could pull such thing off in say Javascript or PHP but (as far as I know) not in Java. And when you get to the bottom of it - Salesforce is built on Oracle database and Java so Apex is kind of thin wrapper on Java calls they deemed most necessary.
Just out of curiosity - why would you need that?
Use Jeremy's idea with loops if you need sequential access. Or...
If you need "unique key -> some value", use Maps.
Map<String, Double> myMap = new Map<String, Double>();
for(Integer i = 1; i < 10; ++i){
myMap.put('someKey' + String.valueOf(i),Math.floor(Math.random() * 1000));
}
System.debug(myMap);
System.debug(myMap.get('someKey7'));
The "double" in this example can be equally Integer, Id, Account, MyCustomClass... whatever your function returns.
There's one more trick I can think of that might be helpful if your data comes from external source. It's to use JSON / XML parsers that could cast any kind of data (held in a String) to a collection of your choice. It kind of goes back to List/Map idea but it's totally up to you how would you build / retrieve this string beforehand. Read about JSON methods for a start although if you don't have a structure that follows predictable pattern you might want to check out JSON/XML parsers (click here and scroll down to the examples).
This isn't possible in apex. You could however use a list:
List<String> values = new List<String>();
for (Integer i = 0; i < aList.size(); i++) {
values.add(dosomething(i));
}

Google Forms as Multiple Choice Quiz - How to Provide Results

I've built a google form for a multiple choice quiz, with a linked spreadsheet for results, which works very well. I have a specific problem, which is that I'd like to present the user's results to them (i.e. how many answers they got right/wrong). The approach I've taken so far is:
create an extra sheet on the spreadsheet with a formula to calculate the number of correct answers for each response. This gives me two columns "Full Name" and "Scores"
embed the form into a google site
create a google apps script to read the results sheet and display output
embed the above into the same site below the form as an Apps Script Gadget
Currently I am able to display all of the results recorded so far. See here:
https://sites.google.com/site/mcqtest123/home
The script looks like:
// Script-as-app template.
function doGet() {
var app = UiApp.createApplication();
var title = app.createLabel("Survey Results").setStyleAttribute("fontSize","16px");
app.add(title);
//readRows(app);
calculateScores(app);
return app;
};
function calculateScores(app) {
var sheet = SpreadsheetApp.openById("0AlNR-ou0QtandFFzX1JCU1VRdTl0NVBRNTFjOUFhd1E");
var responseSheet = sheet.getSheetByName("Form Responses");
var allData = responseSheet.getDataRange().getValues();
var correct = allData[1];
var responses = allData.slice(2);
//Logger.log("Timestamp, name, score");
Logger.log("Name, Score");
for (var i = 0; i < responses.length; i++) {
var timestamp = responses[i][0];
var name = responses[i][1];
var score = 0;
for (var j = 2; j < correct.length; j++) {
if(responses[i][j] == correct[j]) {
score += 1;
}
}
//var output = timestamp + ", " + name + ", " + score + "/" + correct.length
var output = name + ", " + score + "/" + correct.length
print(app, output);
}
};
function print(app, line) {
Logger.log(line);
app.add(app.createLabel(line));
};
So this leaves two problems:
When the page loads, it loads the scores for all the respondents. I'd like to be able to present only the score for the person who filled out the form.
The scores don't get updated when the form is completed - only when the page is refreshed.
For problem 1), I wondered if there was some way to access the data in the form iframe (e.g. using document.getElementById('targetFrame'), except that google scripts don't seem to have access to the document model) to only display results of the person whose full name matches the name in the form (of course you could then view someone else's results if you know what they'd put as their full name, but without using the timestamp I don't see away round this).
For problem 2), I wondered if there was some way to trigger the script when the responses sheet was updated. However when I go to the spreadsheet and Tools->Script Manager I get the message "No scripts found", so I don't know how to add this trigger.
If you make your own form using HtmlService or UiApp and then that POSTing to your script to populate the spreadsheet, then you can generate a UID in a hidden field and use this to determine the results someone needs to see.
This will be the results as instant feedback to their answers to the quiz. To see these at a later date, you could then also add a bookmarkable link that also included that UID as a parameter. So your doGet() would look for a e.parameters.uid for example.
From Google Forms as they stand I am not so sure. you could potentially, with the new form styles, offer a pre-filled field with such a UID, but the route from form submission to your webapp is again unclear.

Resources