Boolean Operation Meaning in React Native - react-native

I'm typically a back-end programmer so to assist with some of the initial work i got a project that had a template project set up. I'm trying to understand some things as my first React Native Project and i can't seem to understand what this logic is saying for bgColor? :
const navbarStyles = [
styles.navbar,
bgColor && { backgroundColor: bgColor }
];
Any explanations or references that could help? Appreciate it!

It's called short-circuiting and is a short-hand way of doing:
if (bgColor) { //implies bgColor != undefined (and also != null, != 0 etc)
backgroundColor: bgColor
}

Related

How to change fluent ui primary or secondary text color?

I have a very simple question. It should be very easy. I can't change color of secondaryText in PersonaDisplay.
<Persona
text="{User.displayName}"
secondaryText={User.currentEmployee === 'true' && 'No longer works'}
size={PersonaSize.size48}
imageUrl={'/_layouts/15/userphoto.aspx?size=S&accountname=' + this.props.User.name}
className={User.currentEmployee === 'true' && 'noLongerWorks'}
/>
It does not get my noLongerWorks class properties :
.noLongerWorks {
color: "red";
}
I went over the docs but see nothing, probably missing a minor spot. I tried to add manual styling as well but no lock.
I found the answer who is interested. You don't need to add a class to change the styling, you can pass styles pros to apply to whatever props of Persona component.
<Persona
text="{User.displayName}"
secondaryText={User.currentEmployee === 'true' && 'No longer works'}
size={PersonaSize.size48}
imageUrl={'/_layouts/15/userphoto.aspx?size=S&accountname=' + this.props.User.name}
**styles={{
secondaryText: {
color: 'red',
},
}}**
/>

Refer to a key in map to add content. React native

I am doing an app that gets information about a sports game from a provider. They provide goals and assists in two different objects, looks something like this:
incidents: {
1: {
id: 1,
type: 'goal'
},
2: {
id: 2
type: 'assist'
referto: 1
}
As you can see in the object above, the object with id 2 is an assist which refers to object with id 1.
So I want to map this object and return a <View> with the data, and if type = assist, I want it to append to the View which the id refers to.
Below is a mix of jQuery and React, but I hope you understand.
Object.map(incident => {
if (incident.type === 'assist') {
incident.referto.append( //refer to the View with key = incident.referto
<View><Text>I am an assist to the goal above</Text></View>
);
}
)};
How can I do something like this?
Thanks in advance!
EDIT:
I want to add "assist" view component inside the "goal" view component. I hope that will make it a bit clearer, sorry.
Best way of going at it is to use a conditional render.
{
incident.type === 'assist' &&
<View>
<Text>I am an assist to the goal above</Text>
</View>
}
By doing so you add the views only when incident type is assist, otherwise they are non-existent.
While not advised, another way of going at it would be to abuse React.createElement(component, props, ...children). However, such a solution is likely not what you want, and probably what you wish to achieve can be achieved using JSX.

React Native: Can't use this.setState() to set a variable inside a 2D array, but this.state.x= works

I have a 2D array of objects with key/value pairs as a state variable, and I'm trying to use the recommended way of setting/changing state variables, which is to use this.setState({x:y}) instead of directly setting it using this.state.x = y and then forceUpdate(). However, when I try to do that, it gives me an "unexpected token" error.
I basically want to flip a variable from one state to the other, so I'm usng a ternary operator. This code works
toggleBookmark(category, index) {
this.state.menuItems[category][index].bmIcon = (this.state.menuItems[category][index].bmIcon === "bookmark-o") ? "bookmark" : "bookmark-o";
}
This code, which I'd expect to do the same thing, gives an error
toggleBookmark(category, index) {
this.setState({menuItems[category][index].bmIcon: (this.state.menuItems[category][index].bmIcon === "bookmark-o") ? "bookmark" : "bookmark-o"});
}
I thought it might be the ternary operator, so I put the value into a variable and tried setting the state variable with that, but it still gives the same error.
toggleBookmark(category, index) {
var iconText = (this.state.menuItems[category][index].bmIcon === "bookmark-o") ? "bookmark" : "bookmark-o";
this.setState({menuItems[category][index].bmIcon: iconText});
}
Am I doing something wrong? Is what I want to do possible with setState()?
In Javascript, you cannot use an expression as a key for an object when creating that object inline.
The problem here is that you have done {menuItems[category][index].bmIcon: iconText} which will throw a syntax error.
If you want a quick way to solve this, you may create the object first, then assign the value to that key like this:
var state = {};
state[menuItems[category][index].bmIcon] = iconText;
this.setState(state);
It's worth noting however that ES6 Provides a sugar for doing this, and there is another answer here that might provide more insight
How do I create a dynamic key to be added to a JavaScript object variable
Update:
I now see what you meant, I had previously assumed that menuItems already defined, but what you want to do is change the value of a key inside a nested object that is in this.state
This is something that React is not really built to do, you should keep your state relatively simple, and make separate React components for each menu item, then have them manage their own state. I would strongly recommend this approach because it will keep your code clean and robust. Don't be afraid to make more components!
However if you do want to keep all this nested state in one component (not advised), then you should first make a copy of the object you want to setState on.
var newMenuItems = _.clone(this.state.menuItems);
var iconText = (this.state.menuItems[category][index].bmIcon === "bookmark-o") ? "bookmark" : "bookmark-o";
newMenuItems[category][index].bmIcon = iconText;
this.setState({ menuItems: newMenuItems });
OR
var iconText = (this.state.menuItems[category][index].bmIcon === "bookmark-o") ? "bookmark" : "bookmark-o";
this.state.menuItems[category][index].bmIcon = iconText;
this.forceUpdate();
(First method preferred, but it requires you have something like underscore or lodash installed )
I have the data chat:
chat: {
id: 'ss3k5e6j1-6shhd6-sdasd3d3-23d5-gh67',
agentName: 'egaliciar',
agentAvatar: 'http://i.imgur.com/DY6gND0.png',
messages: [
{
id: 1,
lines: [
'Me pueden ayudar?',
'Tengo problemas con mis boletos',
'Hola buen dia...',
],
time: '17:20',
},
{
id: 2,
lines: ['¿Me podria regalar su nombres', 'Con gusto...'],
time: '17:22',
date: '23/ene/2012',
},
],
},
};
and when i do
const oldLines =Object.assign({}, this.state.chat);
oldLines.messages[0].lines.push('newValue');
My state Changed..... without this.setState({});
I Made a Clone;
var clone = JSON.parse(JSON.stringify(this.state.chat));
clone.messages[0].lines.push('new Value');
and the State maintain their state;
thus, the complete solution is for me:
var clone = JSON.parse(JSON.stringify(this.state.chat));
clone.messages[0].lines.push(questionAreaMessage); //the state maintains
this.setState({chat:clone}); //here the State change!!!!

Organizing JS code with Alloy and CommonJS in Titanium projects

I'm learning with Titanium to make iPhone/Android apps. I'm using Alloy MVC framework. I never used javascript before, apart from simple scripts in HTML to access the DOM or something like that, so I never needed to structure the code before.
Now, with Titanium, I must use a lot of JS code and I was looking for ways to structure my code. Basically I found 3 ways to do it: prototype, namespace and functions inside functions.
Simple example for each:
Prototype:
NavigationController = function() {
this.windowStack = [];
};
NavigationController.prototype.open = function(windowToOpen) {
//add the window to the stack of windows managed by the controller
this.windowStack.push(windowToOpen);
//grab a copy of the current nav controller for use in the callback
var that = this;
windowToOpen.addEventListener('close', function() {
if (that.windowStack.length > 1)
{
that.windowStack.pop();
}
});
if(Ti.Platform.osname === 'android') {
windowToOpen.open();
} else {
this.navGroup.open(windowToOpen);
}
};
NavigationController.prototype.back = function(w) {
//store a copy of all the current windows on the stack
if(Ti.Platform.osname === 'android') {
w.close();
} else {
this.navGroup.close(w);
}
};
module.exports = NavigationController;
Using it as:
var NavigationController = require('navigator');
var navController = new NavigationController();
Namespace (or I think is something like that, coz the use of me = {}):
exports.createNavigatorGroup = function() {
var me = {};
if (OS_IOS) {
var navGroup = Titanium.UI.iPhone.createNavigationGroup();
var winNav = Titanium.UI.createWindow();
winNav.add(navGroup);
me.open = function(win) {
if (!navGroup.window) {
// First time call, add the window to the navigator and open the navigator window
navGroup.window = win;
winNav.open();
} else {
// All other calls, open the window through the navigator
navGroup.open(win);
}
};
me.setRightButton = function(win, button) {
win.setRightNavButton(button);
};
me.close = function(win) {
if (navGroup.window) {
// Close the window on this nav
navGroup.close(win);
}
};
};
return me;
};
Using it as:
var ui = require('navigation');
var nav = ui.createNavigatorGroup();
Functions inside functions:
function foobar(){
this.foo = function(){
console.log('Hello foo');
}
this.bar = function(){
console.log('Hello bar');
}
}
// expose foobar to other modules
exports.foobar = foobar;
Using it as:
var foobar = require('foobar').foobar
var test = new foobar();
test.bar(); // 'Hello bar'
And now my question is: which is the better to maintain code clean and clear? It seems that prototype is clear an easy to read/mantain. Namespace confuses me a bit but only needs to execute the initial function to be "available" (no use of new while declaring it, I suppose because it returns the object?namespace? "me"). Finally, functions inside functions is similar to the last, so I don't know exactly the difference, but is useful to export only the main function and have all the inside functions available for use it later.
Maybe the last two possibilities are the same, and I'm messing concepts.
Remember that I'm searching for a good way to structure the code and have functions available to other modules and also inside the own module.
I appreciate any clarification.
In the examples that they release, Appcelerator appears to follow the non-prototype approach. You can see it in the examples they have released: https://github.com/appcelerator/Field-Service-App.
I've seen a lot of different approaches to structuring applications in Titanium before Alloy. Since Alloy, I've found following the development team's examples helpful to me.
With that being said, it seems to me that all of this is still under interpretation and open to change and community development. Before Alloy there were some great community suggestions on structuring an app and I believe that it is still open with Alloy. Often when I find someone's example code I see something they did with it that appears to organize it a bit better than I thought of. It seems to make it a bit easier.
I think you should structure your application in a way that makes sense to you. You may stumble on to a better and easier way of developing applications with Alloy, because you are looking at it critically.
I haven't found a lot of extensive Alloy examples, but Field-Service-App makes sense to me. They have a nice separation of the elements in the application beyond MVC. Check it out.

Javascript Style Sheet in Titanium mobile

I'm a learning mobile development using Titanium Mobile framework.
I am facing a problem related to application of javascript style sheet.
When I name my jss file same as the js file, to which the style is to be applied, it works fine. But if I name it something else, it don't work. Can anybody tell me a solution. Following is my code sample.
// app.js
var win = Titanium.UI.createWindow({ backgroundColor : '#fff' });
win.add( Ti.UI.createButton({ title : 'Button A' }) );
win.open();
// app.jss, works fine
button { backgroundImage: 'grdadient_img.png'; }
// button_style.jss, don't work
button { backgroundImage: 'grdadient_img.png'; }
I never had much success using more than one JSS file. And if you follow Nandu's links you'll see that it's not really documented very well, likely to be removed from Titanium at some point. I expect that Titanium's Alloy will kill off JSS too.
If you don't want to use JSS (or Alloy yet), there is a neat way to centralise your styles using commonJS modules and optionally underscore.js e.g.
theme.js
var theme = {
tableLabel : {
color : '#3285C7',
backgroundColor : 'transparent',
inactiveColor : '#AAAAAA'
}
}
module.exports = theme;
to use
var theme = require('ui/common/Theme');
...
var myLabel = Ti.UI.createLabel(_.extend({}, theme.tableLabel, {
top : 5,
height : Ti.UI.SIZE,
width : Ti.UI.FILL,
text : "Hello world",
}));
I use _extend to take the settings from the theme and add instance specific settings like size, position etc. Don't forget the first empty object literal in the call to `_.extend()
See http://underscorejs.org/#extend
Ammar, please refer the following links. Hope it will help you
1.How to use jss correctly
2.How Does .jss feature really works in Titanium mobile SDK