I have many functions (funcOne, funcTwo, etc.), all of them share the same block of checks at the beginning (I want to move those blocks to a separate function or something so I'm not repeating code, but the problem is that I use return. Please read on)
If any of these checks fail, I output a specific message that this specific check failed, and return (so the actual code of the function doesn't execute)
If all checks pass, the function continues to the specific code of the function.
What I want to do is move those checks to a separate function. But the problem is that I'm using return; which would return out of the new function, but wouldn't return from funcOne and funcTwo. Can someone help me refactor this code so I don't have to repeat the duplicate checks in every function that uses them.
protected function funcOne(event:MouseEvent):void
{
if( check 1 doesn't pass){
Alert.show("error 1, returning);
return;
}
if( check 2 doesn't pass){
Alert.show("error 2, returning);
return;
}
.... more checks here, all of them return specific messages
//if all checks pass
//execute the specific code of this funcOne
}
protected function funcTwo(event:MouseEvent):void
{
if( check 1 doesn't pass){
Alert.show("error 1, returning);
return;
}
if( check 2 doesn't pass){
Alert.show("error 2, returning);
return;
}
.... more checks here, all of them return specific messages
//if all checks pass
//execute the specific code of this funcTwo
}
protected function funcOne(event:MouseEvent):void
{
if( !checkAll(event) ){
return;
}
//if all checks pass
//execute the specific code of this funcOne
}
protected function funcTwo(event:MouseEvent):void
{
if( !checkAll(event) ){
return;
}
//if all checks pass
//execute the specific code of this funcTwo
}
private function checkAll(event:MouseEvent):Boolean
{
if( check 1 doesn't pass){
Alert.show("error 1, returning);
return false;
}
if( check 2 doesn't pass){
Alert.show("error 2, returning);
return false;
}
return true;
}
You can build a string of errors in your error checking function, then return that string to your main function. If the string has contents, display it and break your program;
protected function funcOne(event:MouseEvent):void
{
errors = checkForErrors();
if( errors != null || errors != "" )
{
Alert.show( errors );
return;
}
}
protected function checkForErrors():String
{
var errorString:String = '';
if( check 1 doesn't pass){
errorString +="error 1\n";
}
if( check 2 doesn't pass){
errorString +="error 1\n";
{
return errorString;
}
Here's a quick way to do it. You could also return the actual message string if you want to handle the alert elsewhere. If the message string is null, then there's no error.
protected function funcOne(event:MouseEvent):void
{
if(validate())
{
//if all checks pass
//execute the specific code of this funcOne
}
}
protected function funcTwo(event:MouseEvent):void
{
if(validate())
{
//if all checks pass
//execute the specific code of this funcOne
}
}
//returns false if not valid
protected function validate():Boolean
{
var errorMessage:String = null;
if( check 1 doesn't pass)
errorMessage = "error 1, returning";
else if( check 2 doesn't pass)
errorMessage = "error 2, returning";
if(errorMessage)
Alert.show(errorMessage);
return !errorMessage as Boolean; //will return true if errorMessage is null
}
Related
I'm trying to run a check on a webdb running on a cordova/jQuery-mobile application:
This function will check whether the table exists in the DB and subsequently return a true or false. I have tried to change the return type from boolean to integer (0 and 1) but with no success.
function checkConfigTable(tablename) {
db.transaction
(
function (tx)
{
tx.executeSql
(
'SELECT name FROM sqlite_master WHERE type="table" AND name=?',
[tablename],
function(tx,results)
{
var len = results.rows.length;
if(len>0)
{
return true;
}
else {
return false;
}
}, errorCB
);
},errorCB,successCB
);
}
I want to then call checkConfigTable from this other one just to alert the return value (only for test purposes at the moment) but I am always getting "undefined" as return value.
// Function to retrieve current login config
function getSavedLogin(configid) {
var x = checkConfigTable("config");
alert('table: ' + x);
}
If I substitute the return with an alert directly in checkConfigTable() the correct values are shown in the alert box.
I am creating a method that will take a collection of different types (divs, spans..) and search it. I can't find a parameter to pass different collection types though. I tried IElementContainer and ElementCollections but I can't cast DivCollection to either. Is there another way?
The method that does the search:
private static ElementCollection searchCollections(IElementContainer ec, WACore.compStringInfo info)
{
if (info.componentIDName == WACore.componentIDs.Id.ToString())
{
return ec.Elements.Filter(Find.ById(info.componentIDValue));
}
else if (info.componentIDName == WACore.componentIDs.Name.ToString())
{
return ec.Elements.Filter(Find.ByName(info.componentIDValue));
}
else if (info.componentIDName == WACore.componentIDs.Title.ToString())
{
return ec.Elements.Filter(Find.ByTitle(info.componentIDValue));
}
else if (info.componentIDName == WACore.componentIDs.OuterText.ToString())
{
String str = info.componentIDValue.Substring(1, 6);
return ec.Elements.Filter(Find.ByText(new Regex(str)));
}
else
{
return null;
}
}
The caller(s):
return searchCollections((IElementContainer)doc.TextFields, info);
return searchCollections((IElementContainer)(doc.Divs), info);
return searchCollections((IElementContainer)doc.Spans, info);
codeigniter recursive model function returning blank but when printing it in the model showing properly
here is my code,
for controller
$commision_arr=$this->billing_model->root_commision($category_manager['id']);
and in the model
public function root_commision($id)
{
$sql="SELECT * FROM tbl_mst_category WHERE id = '".$id."'";
$query = $this->db->query($sql);
$row=$query->row_array();
if($row['parent']!=0)
{
$this->root_commision($row['parent']);
}
else
return $row;
}
recursion is tricky huh?
i think the problem is that you were only returning the id for the deepest element, but not returning that to the calling method -- so it would only work for the case where the parent id was called. i can't test the code below, but it should point you in the right direction. NB, it returns the row as an object, not as an array as your code does.
On a more academic note, if the table is large it may be better to pre-calculate these root ids for each of these categories. it will make the query much faster -- recursion is not fast. look at transitive closures
public function root_commision($id,$root_found = FALSE)
{
// returns FALSE if the id is not found, or the parent row.
$query = $this->db->get_where('tbl_mst_category', array('id' => $id));
if ($query->num_rows() > 0 )
{
$row = $query->first_row();
if (($row->parent ) != 0 )
{
return $this->root_commision($row_id);
}
else
{
return $row;
}
}
else
{
return FALSE;
}
}
you have to return function at the calling time then only you can get
the value of recursive function just add "return" keyword before function call.
public function root_commision($id)
{
$sql="SELECT * FROM tbl_mst_category WHERE id = '".$id."'";
$query = $this->db->query($sql);
$row=$query->row_array();
if($row['parent']!=0)
{
return $this->root_commision($row['parent']);
}
else
return $row;
}
For all users I need to conditionally block access to nodes of type 'message'. The only way users should be able to view these message nodes is by successfully submitting a form.
I've started like this:
function mymodule_node_access($node, $op, $account) {
if ($op == 'view' && $node->type == 'message') {
return NODE_ACCESS_DENY;
}
}
However, I want to allow view access to individual nodes of this type upon successful submission of form:
function form_submit($form, &$form_state) {
// some logic here
$form_state['redirect'] = 'node/255';
}
so node 255 is of type 'message', and I want to 'lift' the NODE_ACCESS_DENY for this particular node and this user (+ in most cases this will be an anonymous user)
Any suggestions on different ways to accomplish this?
The only way you can do that is to set a value in the form submission handler that is then checked by hook_node_access(); you could use a Drupal variable, or a value saved in a database table.
You need to store the user ID of the user that accessed the form, and the node ID of every node for which such form has been submitted.
Supposing you use a Drupal variable, you could use code similar to the following one:
function mymodule_form_submit($form, &$form_state) {
global $user;
$message_nid = 255;
$values = variable_get('access_nid', array());
if (isset($values[$user->uid])) {
if (!isset($values[$user->uid][$message_nid])) {
$values[$user->uid][$message_nid] = $message_nid;
}
}
else {
$values[$user->uid] = array($message_nid => $message_nid);
}
variable_set('access_nid', $values);
$form_state['redirect'] = 'node/' . $message_nid;
}
function mymodule_node_access($node, $op, $account) {
$result = NODE_ACCESS_IGNORE;
if ($op == 'view' && $node->type == 'message') {
$values = variable_get('access_nid', array());
if (!empty($values[$account->uid]) {
if (isset($values[$account->uid][$node->nid])) {
unset($values[$account->uid][$node->nid]);
$result = NODE_ACCESS_ALLOW;
}
else {
$result = NODE_ACCESS_DENY;
}
}
else {
$result = NODE_ACCESS_DENY;
}
}
variable_set('access_nid', $values);
return $result;
}
To notice that this code allows a user to access a node only once; if the user would try to access the same node the second time, the user would get an "access denied" error. If that is not desired, then the second function should be re-written as follows:
function mymodule_node_access($node, $op, $account) {
if ($op == 'view' && $node->type == 'message') {
$values = variable_get('access_nid', array());
if (!empty($values[$account->uid]) {
if (isset($values[$account->uid][$node->nid])) {
return NODE_ACCESS_ALLOW;
}
return NODE_ACCESS_DENY;
}
}
else {
$result = NODE_ACCESS_DENY;
}
}
return NODE_ACCESS_IGNORE;
}
I used a Drupal variable to write simple code; using a Drupal variable, in this case, should be done if the users that can create nodes of that content type are few; if there are many users who can create those nodes, then using a database table is better.
Also when using Drupal variables, Drupal is using a database table; the difference is that the content of that database table is always loaded in memory. If you need to store many data, you should not use Drupal variables.
Modified solution to use $_SESSION as I'm working mostly with anonymous users:
function mymodule_form_submit($form, &$form_state) {
$message_nid = 255;
if (!isset($_SESSION['node_access'])) {
$_SESSION['node_access'] = array();
}
if (!isset($_SESSION['node_access']['nid'])) {
$_SESSION['node_access']['nid'] = $message_nid;
}
$form_state['redirect'] = 'node/' . $message_nid;
}
function mymodule_node_access($node, $op, $account) {
$node_access = NODE_ACCESS_IGNORE;
if ($op == 'view' && $node->type == 'message') {
if (isset($_SESSION['node_access'] && !empty($_SESSION['node_access'])) {
if ($node->nid == $_SESSION['node_access']['nid']) {
unset($_SESSION['node_access']['nid']);
$node_access = NODE_ACCESS_ALLOW ;
} else {
unset($_SESSION['node_access']['nid']);
$node_access = NODE_ACCESS_DENY;
}
} else {
$node_access = NODE_ACCESS_DENY;
}
}
return $node_access;
}
I have an if statement inside an if statement.
If the condition in the second if statement returns false, I want to go to the first else
because there it sets my validation controls automatically.
I hope you understand
if (page.isvalid() )
{
if (datetime.tryparse (date) == true)
{
// ok
}
else
{
//go to the other else
}
}
else
{
// want to go here
}
Edit:
Important is that I have to first validate the page because after the validation, I know I can parse the datetimes from the 2 input controls and check if the second one is greater than the first one. Otherwise it throws an exception, maybe, if the date is not valid.
instead of DateTime.Parse(date) use
DateTime dt;
bool isParsed = DateTime.TryParse(date, out dt);
//if ( page.isvalid() && (datetime.parse (date) == true) )
if ( page.isvalid() && isParsed )
{
// ok
}
else
{
// want to go here
}
Take out the elses, and it should be what you're looking for. Also, add a return statement after everything is good to go.
if ( page.isvalid() )
{
if (datetime.parse (date) == true)
{
// ok
}
return;
}
// code here happens when it's not valid.
This does exactly what you want, I believe.
if (page.isvalid() && datetime.tryparse(date) == true)
{
// ok
}
else
{
// want to go here
}
It is not clear whether the '== true' is necessary; you might be able to drop that condition.
Exactly what you want to do is impossible. There are two options. One is to determine both answers at the top of your if clause. This is what the other posters are telling you to do. Another option would be something like this:
bool isvalid = true;
if ( page.isvalid() )
{
if (datetime.tryparse (date) == true)
{
// ok
}
else
{
isvalid = false;
}
}
else
{
isvalid = false;
}
if (isvalid == false)
{
//do whatever error handling you want
}
This extracts the error handling code from your else clause and puts it somewhere both code paths can reach.