Q:How to if contidion from json on React in one component? - javascript

I want to make the type of product to add and hide things, can I use only one component because I do it right now with two. I have an if that renders ProductNew and ProductOld. Is it possible to make the differences in one compartment or not?
This is the json:
{
"products": {
"product": {
"type": "new",
"new": {
"text": "Some text..."
},
"attr": {
"price": "20"
}
},
"product2": {
"type": "old",
"attr": {
"price": "10"
}
}
}
}

It is possible, yes. Just pass the type as a property into your single component and then move the if statements into that.
So the calling code would look like
<YourComponent type="{this.props.type}" />
and the component would have, for example
<div>
{this.props.type == "New" ?
<span>New Stuff</span> :
<span>Old Stuff</span>
}
</div>
if you don't want anything in the old then just use
<div>
{this.props.type == "New" ?
<span>New Stuff</span> :
null
}
</div>

Related

How to exhibit a json with internal vectors?

So, I have to split a json, but I don't know how. I need that the name of a category goes shows in a tab. Here's a example of my json:
"tabs": [
{
"General": [
{
"created_at": "2019-11-29 11:32:11",
"name":'Test 1'
},
{
"created_at": "2019-11-29 11:32:11",
"name":'Test 2'
},
]
},
{
"One More": [
{
"created_at": "2019-11-29 15:01:55",
"name": "Test 3"
}
]
}
]
The tab code I understand (is like this: https://react-bootstrap.github.io/components/tabs/), my problem is just show "General" or "One More" on the tab name, and the name changes... I know is a silly question, but I can't find a good explanation.
Thanks for the help!
Following the docs to render one tab for each key of tabs
<Tabs defaultActiveKey="profile" id="uncontrolled-tab-example">
{
Object.keys(tabs).map(key =>(
<Tab title={key} key={key}>
Foo
</Tab>
))
}
</Tabs>
Object.keys(myObject) will provide you an array of strings representing each property of the original object

How to create dynamic nested accordion in React Native

All of the examples I've found online only show how to create single level accordion, like this:
-parent1
-child1
-parent2
-child2
I need to create dynamic accordion that has multiple nested parents, like this:
-parent
-subparent1
-subparent2
...
-subparentN
- child
My data comes in this format:
// first object in response is always considered to be the PARENT,
last one is always CHILD, and those in between are SUBPARENTS
// number of SUBPARENTS is not constant
"parents": [
{
"id": "583", // TOP LEVEL PARENT
"label": "PARENT",
"description": "irrelevant description here, i only need to show label for parents"
},
{
"id": "593",
"label": "SUBPARENT1",
"description": "..."
},
{
"id": "594",
"label": "SUBPARENT2",
"description": "..."
},
{
"id": "604",
"label": "SUBPARENT3",
"description": "..."
},
{
"id": "605", // CHILD
"label": "CHILD LABEL",
"description": "FEW LINES OF DESCRIPTION I NEED TO DISPLAY"
}
]
Based on the component you linked, it might be a good idea to have each as its own array (parent, subparent, an child label), and render its own collapsible.
For parent, have an accordion inside _renderContent function, and have that accordion be filled with its subparent. For subparent with child, have their _renderContent be filled with its child's content as well.
For parent's renderContent (see its sections props)
_renderContent = section => {
return (
<View style={styles.content}>
<Accordion
sections={SUBPARENT_SECTIONS}
activeSections={this.state.activeSections}
renderSectionTitle={this._renderSectionTitle}
renderHeader={this._renderHeader}
renderContent={this._renderContent}
onChange={this._updateSections}
/>
</View>
);
};
For subparent, do the same thing with its child label. It's probably a good idea not to have them on the same array, so you don't confuse them together.

React, javascript object, if key value exists render an element

How do I check to see if a javascript object item has a key and render an element if it does exist.
This is my javascript object which is then parsed through and each item is made into a bootstrap list item. Under items.title = Groups, there is an additional key "dropdown": "true" which is the element I would like to create a dropdown menu for.
var linksNav = {
items: [
{
"type": "heading",
"title": "News",
"href": "#",
"target": "_self"
},
{
"type": "link",
"title": "People",
"href": "#",
"target": "_self"
},
{
"type": "link",
"title": "Events",
"href": "#",
"target": "_self"
},
{
"type": "link",
"title": "Groups",
"href": "#",
"target": "_self",
"dropdown": "true"
},
{
"type": "heading",
"title": "Capabilities",
"href": "#",
"target": "_self"
},
{
"type": "link",
"title": "Initiatives",
"href": "#",
"target": "_self"
},
{
"type": "link",
"title": "Who we are",
"href": "#",
"target": "_blank"
},
]
}
And this is my code (that doesn't work) to try to conditionally render a dropdown (the <NavSub /> tag) if that key exists for that menu item.
The result I get is my dropdown menu for each of my list items is <div>Nothing</div>. Everything else shows up as normal, so I figure there's something wrong with my conditional statement.
render: function() {
let dropdownMenu;
if (this.props.dropdown=="true") {
dropdownMenu = (<Navsub />)
} else {
dropdownMenu = (<div>Nothing</div>)
}
return (
<li className={this.props.title + ' nav-items'}>
{this.props.title}
//I want to conditionall render this dropdown menu
<ul className="dropdown-menu fade">
{dropdownMenu}
</ul>
</li>
);
}
If "dropdown" may not be present in your props, you should use JavaScript's in operator. Also, avoid using == as it can lead to weird results due to silent type conversions.
if ('dropdown' in this.props && this.props.dropdown === 'true') {
//show dropdown
} else {
//don't show dropdown
}
The previous snippet works because JavaScript's if short-circuits.
Having said that, given that you're getting a div containing Nothing in each dropdown, it's likely your components are not receiving the props they're supposed to. You should check what props each component is getting.
This approach may be overkill for your situation where the following will work for your situation:
if ((this.props.dropdown) && this.props.dropdown === "true"){
dropdownMenu = <Navsub />;
} else {
dropdownMenu = <div>Nothing</div>
}
An alternative approach to checking whether the property dropdown exists on the object this.props, you can use Object#hasOwnProperty with the shortcut && binary operator in your condition:
// the condition will only check if dropdown is true if it exists on this.props
if (this.props.hasOwnProperty('dropdown') && this.props.dropdown === "true") {
dropdownMenu = <Navsub />;
} else {
dropdownMenu = <div>Nothing</div>
}
Object#hasOwnProperty is useful in scenarios where you want to
ensure that the property exists on the object even in the case where
its value is null or undefined.

Is there a way to use a property in JSON in another value of a property?

Not sure if the question makes sense so better to provide a code example.
{
"data": {
"whatever": [{
"id": "abcd12312",
"title": null,
"value": null,
"options": [
{
"text": "My text {{value}} one",
"value": "email#address.com"
},
{
"text": "My text [value] one",
"value": "email#address.com"
}
]
}]
}
}
So I was thinking can you do anything with Mustache or is there another way without having to write JavaScript to insert the value inside the text?
What I am trying to do is to allow the user to change the text to what ever they want but have a pointer to the value which will be dynamic based on what email address the entered on a previous page.

Populate AngularJS {{expression}} within ng-repeat using a second array

I'm completely rebuilding my website (originally hacked together with Wordpress) using Laravel and AngularJS. It's been a massive learning experience and I think I'm nearly there but for one problem.
On my site 'schemes' (or courses) are made up of 'units' which are made up of 'lessons'. Retrieving this data is fine, using Eloquent I retrieve valid JSON like this made up example...
[
{
"id": "1", //Scheme Id
"title": "Sports",
"description": "This is a Sports course!",
"units": [
{
"id": "1",
"title": "Tennis",
"lessons": [
{
"id": "6",
"title": "Serving"
},
{
"id": "7",
"title": "Hitting the ball with top-spin"
}
]
},
{
"id": "2",
"title": "Athletics",
"lessons": [
{
"id": "1",
"title": "Long Jump"
},
{
"id": "2",
"title": "Hurdling Technique"
}
]
},
{
"id": "4",
"title": "Golf",
"lessons": [
{
"id": "4",
"title": "Pitching"
},
{
"id": "5",
"title": "Putting"
}
]
}
]
}
....
]
Separately I have a simple array of completed lesson ids for a particular user like this...
[2, 6, 8, 9] ///User has completed lessons with ids of 2,6,8 and 9
In my view I'm using nested ng-repeat loops like so...
...
<div ng-controller="SchemesController">
<div ng-repeat="scheme in schemes">
<h1>{{scheme.title}}</h1>
<div ng-repeat="unit in scheme.units">
<h3>{{unit.title}}</h3>
<div ng-repeat="lesson in unit.lessons">
<div>{{lesson.title}}: {{status}}</div>
</div>
</div>
</div>
</div><!--[end of ng-controller="SchemesController"]-->
....
SchemesController (v simple!) looks like this...
var app = angular.module('schemesApp', []);
app.controller('SchemesController', function($scope){
$scope.schemes=jsonData;
});
The problem is I have no idea how to populate the {{status}} field which I want to state simply 'Complete' or 'Incomplete. I investigated whether I could somehow add this info to my original array like this...
"lessons": [
{
"id": "6",
"title": "Serving",
"status": "Complete" //populated somehow
},
{
"id": "7",
"title": "Hitting the ball with top-spin",
}
]
but I got nowhere slowly. Is there a way to do this (I've played around with underscore.js and felt this could help?).
Or do I populate {{status}} from creating and calling a javascript function?!?
ANY help that anyone could offer would be incredible. I'm a school teacher and for some sadistic reason I find a bit of programming/web design a fun use of my spare time so I apologise if this is a stupid question. THANKS in advance!!!
btw if anyone has a better 'title' for this question then please let me know.
I'm assuming you don't need to persist the status back to the database...
This is where you're having the problem:
<div>{{lesson.title}}: {{status}}</div>
You really don't need to store the status in your data model, because it's just used for presentation purposes.
Let's say your array of completed lessons is defined like this:
$scope.completedLessons = [1, 2, 3, 4, 5] // Or however you'd assign it
You need to create a function in your scope like this:
$scope.isLessonCompleted = function(lessonId) {
return $scope.completedLessons.indexOf(lessonId) > -1;
};
Then you need to change the html from above to this:
<div>{{lesson.title}}: {{isLessonCompleted(lesson.id) && 'Complete' || 'Incomplete'}}</div>
If lessons are also a model and each lesson should have a status, which isn't a column/field in your table but is something you'll add logic to determine, you could add a custom model accessor by adding the following to your models/Lesson.php:
// Append custom accessor attributes
protected $appends = ['status'];
public function getStatusAttribute() {
// Add logic here
return 'Complete';
}
This way, when you use Eloquent to retrieve your data, you'll also see a status attribute as part of the object, so you could then access it as usual $lesson->status (PHP) or lesson.status (JS).
For more information, see the official Laravel documentation on accessors and mutators

Categories

Resources