问:
Mysqli prepared statement not fetching correct value in each for loop post
I cannot fetch the proper field value for each post using the id I obtained from stripping the link in an rss feed.

MyBB rss feed does not provide the author value in rss feed so I am manually fetching it using the link found in the feed that contains the thread Id. I think I am successfully in getting the correct thread id from the link because I can echo the correct thread id in each post. Because of this, I use the same variable for the thread id in fetching for the author field (username) in my database. I am fetching the username field but it appears same for all the posts, it is actually the last username who posted. I was able to make this properly working, fetching the correct author but because of some crazy things in life and I am really a newbie in this field I was not able to back up and forgot how I did it.

This is the code I use to make the post from the feed:

```<code>            <?php

                //Getting RSS Feed
                $rss = new DOMDocument();
                $rss->load('https://www.cmricths.com/board/syndication.php?fid=2');
                $feed = array();

                foreach ($rss->getElementsByTagName('item') as $node) {
                    $item = array (
                        'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
                        'desc' => $node->getElementsByTagName('encoded')->item(0)->nodeValue,
                        'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
                        'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue,
                        );
                    array_push($feed, $item);
                }

                //Setting Feed Limits
                $fid = 2;
                $limit = 5;

                require_once 'queries/threadcount.php';

                if ($tcount > $limit) {
                    $tlimit = $limit;
                } else {
                    $tlimit = $tcount;
                }

                //Posting the feed
                for($x=0;$x<$tlimit;$x++) {

                    $title = str_replace(' & ', ' & ', $feed[$x]['title']);
                    $link = $feed[$x]['link'];
                    $description = $feed[$x]['desc'];
                    $date = date('l F d, Y', strtotime($feed[$x]['date']));

                    //getting thread id from the link
                    $arr = explode('=', $link);
                    $tid = $arr[1];

                    //fetching the author
                    require_once 'queries/postedby.php';

                    //post summary
                    echo '<h2 class="blog-post-title">'.$title.'</h2>';
                    echo '<p class="blog-post-meta">'.$date.' <em>by: '.$author.' '.$tid.'</em></p>';
                    echo '<p class="mb-0">'.$description.'</p>';
                    echo '<hr />';

                }

            ?>
</code>```

This is the code for fetching the author:

```<code><?php
/*

References:
*jQuery Remote Validation
*https://websitebeaver.com/prepared-statements-in-php-mysqli-to-prevent-sql-injection

*/

// Get Connection Details
require_once 'config.php';

// Setup the connection
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

if($mysqli->connect_error) {

    echo json_encode('Error connecting to database!');
    exit;

} else {

    // Do the validation process
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $mysqli->set_charset("utf8mb4");

    //Prepare the statement
    $stmt = $mysqli->prepare("SELECT `username` FROM `mybb_posts` WHERE `tid` = ?");

    //Bind the parameter
    $stmt->bind_param("i", $tid);

    //Execute the statement
    $stmt->execute();

    //Get the result
    $result = $stmt->get_result();

    //Fetch Data
    $row = $result->fetch_array();

    $author = $row['username'];

}

?>
</code>```

This is my sql data file:

```<code>SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for mybb_posts
-- ----------------------------
DROP TABLE IF EXISTS `mybb_posts`;
CREATE TABLE `mybb_posts`  (
  `pid` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `tid` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `replyto` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `fid` smallint(5) UNSIGNED NOT NULL DEFAULT 0,
  `subject` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `icon` smallint(5) UNSIGNED NOT NULL DEFAULT 0,
  `uid` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `username` varchar(80) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `dateline` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `message` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `ipaddress` varbinary(16) NOT NULL DEFAULT '',
  `includesig` tinyint(1) NOT NULL DEFAULT 0,
  `smilieoff` tinyint(1) NOT NULL DEFAULT 0,
  `edituid` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `edittime` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `editreason` varchar(150) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `visible` tinyint(1) NOT NULL DEFAULT 0,
  PRIMARY KEY (`pid`) USING BTREE,
  INDEX `tid`(`tid`, `uid`) USING BTREE,
  INDEX `uid`(`uid`) USING BTREE,
  INDEX `visible`(`visible`) USING BTREE,
  INDEX `dateline`(`dateline`) USING BTREE,
  INDEX `ipaddress`(`ipaddress`) USING BTREE,
  INDEX `tiddate`(`tid`, `dateline`) USING BTREE,
  FULLTEXT INDEX `message`(`message`)
) ENGINE = MyISAM AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of mybb_posts
-- ----------------------------
INSERT INTO `mybb_posts` VALUES (7, 6, 0, 2, 'Embed Imgur Album Enabled', 0, 1, 'jodilljames.esteban', 1558864524, 'Imgur Album Embed Test\r\n\r\n[imgur]a/b04h89n[/imgur]\r\n\r\nThe quick brown fox jumps over the lazy dog. :D', 0xA29E76CA, 0, 0, 0, 0, '', 1);
INSERT INTO `mybb_posts` VALUES (10, 9, 0, 2, 'Video Embed Test', 0, 1, 'jodilljames.esteban', 1558960466, '[video=youtube]https://www.youtube.com/watch?v=in-2VHDv44Q[/video]', 0xA29E7612, 0, 0, 0, 0, '', 1);
INSERT INTO `mybb_posts` VALUES (11, 10, 0, 2, 'WELCOME MESSAGE FOR SCHOOL YEAR 2019-2020!', 0, 5, 'hermes.vargas', 1559018673, 'The school year 2019-2020 has just started. New friends, new classmates, new teachers, new challenges and new learnings are bound to happen. The journey to success will never easy, as the saying goes, \"the journey of a thousand miles begins with a single step!\" In order to succeed this school year, bear these three (3) important reminders. First, have an open mind to learning. As a student, you learn  knowledge, acquire skills and develop values. Let your mind accept these positivities to make you better. Second, have a loving heart. Respect emanates from love. Let your love for God, country, environment and fellow men overflow in each day. There is no room for chaos in our school And third, have a disciplined soul. Your intelligence is futile without discipline. A disciplined learner will go beyond the borders of success. As I end let me tell you this quote from Eleanor D. Roosevelt, \"the future belongs to those who believe in the beauty of their dreams!\"\r\n\r\n[b]HERMES PACATANG VARGAS, LPT[/b]\r\nPrincipal II', 0xA29E7711, 0, 0, 0, 0, '', 1);
INSERT INTO `mybb_posts` VALUES (6, 5, 0, 7, 'Hello World', 0, 0, 'TheRandomPoster', 1558861460, 'I just wanted you to know that this post is moderated...\r\n\r\nHello Folks!!! :cool:', 0xA29E7604, 0, 0, 0, 0, '', 1);
INSERT INTO `mybb_posts` VALUES (8, 7, 0, 17, 'Forum Membership', 11, 1, 'jodilljames.esteban', 1558869862, '[b][color=#3333ff]Welcome to Claro M. Recto ICT High School Forum Board![/color][/b]\r\n\r\nThis is board is exclusive only for the Faculty, School Club Officers and selected personnel. \r\n\r\nTo request membership access please seek for CMRICTHS ICT Devs: \r\n\r\n[list]\r\n[*][b]Randy A. Rosales[/b]\r\n[*][b]Jun S. Tibay[/b]\r\n[*][b]Maria Mia Soriano[/b]\r\n[*][b]Jodill James A. Esteban[/b]\r\n[/list]\r\n\r\nNon members can still participate and post message threads in our Public Forum ([url=https://www.cmricths.com/board/forumdisplay.php?fid=7]Click Here[/url]). \r\n\r\nThanks.', 0xA29E761E, 0, 0, 0, 0, '', 1);

SET FOREIGN_KEY_CHECKS = 1;

</code>```

I am suppose to be getting the correct author for each thread. So if the thread id is 9 I should be getting jodilljames.esteban as the author and if the thread id is 10 I should be getting hermes.vargas as the author and so on...

答:
If you take some of the code from the queries/postedby.php script and put it at the start of your code, create the prepared statement before you begin any loops then you might find  an approach like the following works.

That said I'm surprised the PHPBB does not allow editing of the RSS to the extent where you can select what is added to the feed... Maybe it does - maybe it doesn't - it's years since I looked at that software.

goodluck, hope it helps a little

```<code><?php
    /*
        Create the db connection and build your prepared statement

    */
    require_once 'config.php';
    $mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
    $stmt = $mysqli->prepare( "SELECT `username` FROM `mybb_posts` WHERE `tid` = ?" );

    if( $stmt ){
        /*
            If the statement was constructed OK then bind a variable to
            the placeholder in the sql statement. This variable will be
            deduced later...
        */
        $stmt->bind_param("i", $tid );

        $rss = new DOMDocument();
        $rss->load('https://www.cmricths.com/board/syndication.php?fid=2');
        $feed = array();

        foreach ($rss->getElementsByTagName('item') as $node) {
            $item = array (
                'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
                'desc' => $node->getElementsByTagName('encoded')->item(0)->nodeValue,
                'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
                'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue,
            );
            array_push($feed, $item);
        }

        //Setting Feed Limits
        $fid = 2;
        $limit = 5;

        /*
            It is unknown what is in this file - if it contains
            a db connection then I'd suggest editing it to
            remove the db connection as one already exists in
            this page/script....
        */
        require_once 'queries/threadcount.php';

        if ($tcount > $limit) {
            $tlimit = $limit;
        } else {
            $tlimit = $tcount;
        }

        //Posting the feed
        for($x=0;$x<$tlimit;$x++) {

            $title = str_replace(' & ', ' & ', $feed[$x]['title']);
            $link = $feed[$x]['link'];
            $description = $feed[$x]['desc'];
            $date = date('l F d, Y', strtotime($feed[$x]['date']));

            //getting thread id from the link
            $arr = explode('=', $link);
            $tid = $arr[1];

            /*

                query db &
                fetch result

            */
            $stmt->execute();
            $result = $stmt->get_result();
            $row = $result->fetch_array();
            $author = $row['username'];
            $stmt->free_result();

            //post summary
            echo '<h2 class="blog-post-title">'.$title.'</h2>';
            echo '<p class="blog-post-meta">'.$date.' <em>by: '.$author.' '.$tid.'</em></p>';
            echo '<p class="mb-0">'.$description.'</p>';
            echo '<hr />';

        }
    } else {
        exit( 'error' );
    }

    $stmt->close();
    $mysqli->close();
?>
</code>```

Body:
I cannot fetch the proper field value for each post using the id I obtained from stripping the link in an rss feed.

MyBB rss feed does not provide the author value in rss feed so I am manually fetching it using the link found in the feed that contains the thread Id. I think I am successfully in getting the correct thread id from the link because I can echo the correct thread id in each post. Because of this, I use the same variable for the thread id in fetching for the author field (username) in my database. I am fetching the username field but it appears same for all the posts, it is actually the last username who posted. I was able to make this properly working, fetching the correct author but because of some crazy things in life and I am really a newbie in this field I was not able to back up and forgot how I did it.

This is the code I use to make the post from the feed:

            <?php

                //Getting RSS Feed
                $rss = new DOMDocument();
                $rss->load('https://www.cmricths.com/board/syndication.php?fid=2');
                $feed = array();

                foreach ($rss->getElementsByTagName('item') as $node) {
                    $item = array (
                        'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
                        'desc' => $node->getElementsByTagName('encoded')->item(0)->nodeValue,
                        'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
                        'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue,
                        );
                    array_push($feed, $item);
                }

                //Setting Feed Limits
                $fid = 2;
                $limit = 5;

                require_once 'queries/threadcount.php';

                if ($tcount > $limit) {
                    $tlimit = $limit;
                } else {
                    $tlimit = $tcount;
                }

                //Posting the feed
                for($x=0;$x<$tlimit;$x++) {

                    $title = str_replace(' & ', ' & ', $feed[$x]['title']);
                    $link = $feed[$x]['link'];
                    $description = $feed[$x]['desc'];
                    $date = date('l F d, Y', strtotime($feed[$x]['date']));

                    //getting thread id from the link
                    $arr = explode('=', $link);
                    $tid = $arr[1];

                    //fetching the author
                    require_once 'queries/postedby.php';

                    //post summary
                    echo '
'.$title.'
';
                    echo '
'.$date.' by: '.$author.' '.$tid.'
';
                    echo '
'.$description.'
';
                    echo '
';

                }

            ?>

This is the code for fetching the author:

<?php
/*

References:
*jQuery Remote Validation
*https://websitebeaver.com/prepared-statements-in-php-mysqli-to-prevent-sql-injection

*/

// Get Connection Details
require_once 'config.php';

// Setup the connection
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

if($mysqli->connect_error) {

    echo json_encode('Error connecting to database!');
    exit;

} else {

    // Do the validation process
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $mysqli->set_charset("utf8mb4");

    //Prepare the statement
    $stmt = $mysqli->prepare("SELECT `username` FROM `mybb_posts` WHERE `tid` = ?");

    //Bind the parameter
    $stmt->bind_param("i", $tid);

    //Execute the statement
    $stmt->execute();

    //Get the result
    $result = $stmt->get_result();

    //Fetch Data
    $row = $result->fetch_array();

    $author = $row['username'];

}

?>

This is my sql data file:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for mybb_posts
-- ----------------------------
DROP TABLE IF EXISTS `mybb_posts`;
CREATE TABLE `mybb_posts`  (
  `pid` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `tid` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `replyto` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `fid` smallint(5) UNSIGNED NOT NULL DEFAULT 0,
  `subject` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `icon` smallint(5) UNSIGNED NOT NULL DEFAULT 0,
  `uid` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `username` varchar(80) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `dateline` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `message` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `ipaddress` varbinary(16) NOT NULL DEFAULT '',
  `includesig` tinyint(1) NOT NULL DEFAULT 0,
  `smilieoff` tinyint(1) NOT NULL DEFAULT 0,
  `edituid` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `edittime` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `editreason` varchar(150) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `visible` tinyint(1) NOT NULL DEFAULT 0,
  PRIMARY KEY (`pid`) USING BTREE,
  INDEX `tid`(`tid`, `uid`) USING BTREE,
  INDEX `uid`(`uid`) USING BTREE,
  INDEX `visible`(`visible`) USING BTREE,
  INDEX `dateline`(`dateline`) USING BTREE,
  INDEX `ipaddress`(`ipaddress`) USING BTREE,
  INDEX `tiddate`(`tid`, `dateline`) USING BTREE,
  FULLTEXT INDEX `message`(`message`)
) ENGINE = MyISAM AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of mybb_posts
-- ----------------------------
INSERT INTO `mybb_posts` VALUES (7, 6, 0, 2, 'Embed Imgur Album Enabled', 0, 1, 'jodilljames.esteban', 1558864524, 'Imgur Album Embed Test\r\n\r\n[imgur]a/b04h89n[/imgur]\r\n\r\nThe quick brown fox jumps over the lazy dog. :D', 0xA29E76CA, 0, 0, 0, 0, '', 1);
INSERT INTO `mybb_posts` VALUES (10, 9, 0, 2, 'Video Embed Test', 0, 1, 'jodilljames.esteban', 1558960466, '[video=youtube]https://www.youtube.com/watch?v=in-2VHDv44Q[/video]', 0xA29E7612, 0, 0, 0, 0, '', 1);
INSERT INTO `mybb_posts` VALUES (11, 10, 0, 2, 'WELCOME MESSAGE FOR SCHOOL YEAR 2019-2020!', 0, 5, 'hermes.vargas', 1559018673, 'The school year 2019-2020 has just started. New friends, new classmates, new teachers, new challenges and new learnings are bound to happen. The journey to success will never easy, as the saying goes, \"the journey of a thousand miles begins with a single step!\" In order to succeed this school year, bear these three (3) important reminders. First, have an open mind to learning. As a student, you learn  knowledge, acquire skills and develop values. Let your mind accept these positivities to make you better. Second, have a loving heart. Respect emanates from love. Let your love for God, country, environment and fellow men overflow in each day. There is no room for chaos in our school And third, have a disciplined soul. Your intelligence is futile without discipline. A disciplined learner will go beyond the borders of success. As I end let me tell you this quote from Eleanor D. Roosevelt, \"the future belongs to those who believe in the beauty of their dreams!\"\r\n\r\n[b]HERMES PACATANG VARGAS, LPT[/b]\r\nPrincipal II', 0xA29E7711, 0, 0, 0, 0, '', 1);
INSERT INTO `mybb_posts` VALUES (6, 5, 0, 7, 'Hello World', 0, 0, 'TheRandomPoster', 1558861460, 'I just wanted you to know that this post is moderated...\r\n\r\nHello Folks!!! :cool:', 0xA29E7604, 0, 0, 0, 0, '', 1);
INSERT INTO `mybb_posts` VALUES (8, 7, 0, 17, 'Forum Membership', 11, 1, 'jodilljames.esteban', 1558869862, '[b][color=#3333ff]Welcome to Claro M. Recto ICT High School Forum Board![/color][/b]\r\n\r\nThis is board is exclusive only for the Faculty, School Club Officers and selected personnel. \r\n\r\nTo request membership access please seek for CMRICTHS ICT Devs: \r\n\r\n[list]\r\n[*][b]Randy A. Rosales[/b]\r\n[*][b]Jun S. Tibay[/b]\r\n[*][b]Maria Mia Soriano[/b]\r\n[*][b]Jodill James A. Esteban[/b]\r\n[/list]\r\n\r\nNon members can still participate and post message threads in our Public Forum ([url=https://www.cmricths.com/board/forumdisplay.php?fid=7]Click Here[/url]). \r\n\r\nThanks.', 0xA29E761E, 0, 0, 0, 0, '', 1);

SET FOREIGN_KEY_CHECKS = 1;

I am suppose to be getting the correct author for each thread. So if the thread id is 9 I should be getting jodilljames.esteban as the author and if the thread id is 10 I should be getting hermes.vargas as the author and so on...

Body:
If you take some of the code from the queries/postedby.php script and put it at the start of your code, create the prepared statement before you begin any loops then you might find  an approach like the following works.

That said I'm surprised the PHPBB does not allow editing of the RSS to the extent where you can select what is added to the feed... Maybe it does - maybe it doesn't - it's years since I looked at that software.

goodluck, hope it helps a little

<?php
    /*
        Create the db connection and build your prepared statement

    */
    require_once 'config.php';
    $mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
    $stmt = $mysqli->prepare( "SELECT `username` FROM `mybb_posts` WHERE `tid` = ?" );

    if( $stmt ){
        /*
            If the statement was constructed OK then bind a variable to
            the placeholder in the sql statement. This variable will be
            deduced later...
        */
        $stmt->bind_param("i", $tid );

        $rss = new DOMDocument();
        $rss->load('https://www.cmricths.com/board/syndication.php?fid=2');
        $feed = array();

        foreach ($rss->getElementsByTagName('item') as $node) {
            $item = array (
                'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
                'desc' => $node->getElementsByTagName('encoded')->item(0)->nodeValue,
                'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
                'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue,
            );
            array_push($feed, $item);
        }

        //Setting Feed Limits
        $fid = 2;
        $limit = 5;

        /*
            It is unknown what is in this file - if it contains
            a db connection then I'd suggest editing it to
            remove the db connection as one already exists in
            this page/script....
        */
        require_once 'queries/threadcount.php';

        if ($tcount > $limit) {
            $tlimit = $limit;
        } else {
            $tlimit = $tcount;
        }

        //Posting the feed
        for($x=0;$x<$tlimit;$x++) {

            $title = str_replace(' & ', ' &amp; ', $feed[$x]['title']);
            $link = $feed[$x]['link'];
            $description = $feed[$x]['desc'];
            $date = date('l F d, Y', strtotime($feed[$x]['date']));

            //getting thread id from the link
            $arr = explode('=', $link);
            $tid = $arr[1];

            /*

                query db &
                fetch result

            */
            $stmt->execute();
            $result = $stmt->get_result();
            $row = $result->fetch_array();
            $author = $row['username'];
            $stmt->free_result();

            //post summary
            echo '<h2 class="blog-post-title">'.$title.'</h2>';
            echo '<p class="blog-post-meta">'.$date.' <em>by: '.$author.' '.$tid.'</em></p>';
            echo '<p class="mb-0">'.$description.'</p>';
            echo '<hr />';

        }
    } else {
        exit( 'error' );
    }

    $stmt->close();
    $mysqli->close();
?>


来源: stackexchange

问:
Create a table in thymeleaf
I'm new to thymeleaf and am trying to make a simple table using an array and an each loop.

My code looks like this:

```<code><!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Smoke Tests</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<table border="1" style="width:300px">
    <tr>
        <td>Test Name</td>
    </tr>
    <tr th:each="smokeTest : ${smokeTests}">
        <td>
            th:text="${smokeTest.name}">A Smoke Test'
        </td>
    </tr>
</table>
</body>
</html>
</code>```

Basically my problem is that I can't run the loop as s within
s. Is there any way that this code could work?

答:
Although, it's late answer.
It's work more specifically, like</p>

```<code><tr th:each="smokeTest : ${smokeTests}">
   <td><p th:text="${smokeTest.name}"></p></td>
</tr>
</code>```

ContentLicense: CC BY-SA 4.0

Title: Create a table in thymeleaf

Body:
I'm new to thymeleaf and am trying to make a simple table using an array and an each loop.

My code looks like this:

<!DOCTYPE HTML>

    <title>Smoke Tests</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

        Test Name

            th:text="${smokeTest.name}">A Smoke Test'

Basically my problem is that I can't run the loop as s within
s. Is there any way that this code could work?

Body:
Although, it's late answer.
It's work more specifically, like

<tr th:each="smokeTest : ${smokeTests}">
   <td><p th:text="${smokeTest.name}"></p></td>
</tr>


问:
Google Play does not show the "Update" feature when I have already manually installed an older version of apk
I have installed an old version (4.0) of my application manually. In Google Play store I have already uploaded a new app with the same package name and incremented the app version to version 5.0. But Google Play store does not show the "Update" button.

This will only occur when the old app is installed manually.It will show the "Update" function on Google Play store.

答:
The update dialog will only show if all of the following are true:

The current user has already installed the app once (on any device), that is, it is in the User's library. This can be checked in the Ply store app by looking in the "My apps and games" menu under "Library"

The package name (application id) for the app is the same

the app is signed with the same key as the the app is published with on the Play store. In the case of Apps enrolled into Google Play app signing, this has to be the Play store key, not the upload key


问:
Is there any tool to optimize MySQL Queries?
I am  undergoing the performance test on MySQL and i need your guidance.If there is any tool available to optimize the MySQL Queries.Please let me know.The tool i am  seeking for is one which would be useful to identify the query which causing the memory leak.

Thanks,

答: Take a look at this one - Query Profiler</p>

ContentLicense: CC BY-SA 3.0


问:
Put multiple values in arrays from cvs file
Values are separated with comma, following format:

```<code>Country,Timescale,Vendor,Units
Africa,2010 Q3,Fujitsu Siemens,2924.742632
</code>```

I want to make array for every value. How can I do it?

I tried many things, code below:

```<code>BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {

    br = new BufferedReader(new FileReader(csvFile));
    while ((line = br.readLine()) != null) {
        String[] country = line.split(cvsSplitBy);
        country[0] +=",";
        String[] Krajina = country[0].split(",");
</code>```

答:
What you appear to be talking about is utilizing what is otherwise known as Parallel Arrays and is generally a bad idea in this particular use case since it can be prone to OutOfBounds Exceptions later on down the road. A better solution would be to utilize a Two Dimensional (2D) Array or an ArrayList. Never the less, parallel arrays it is:

You say an array size of 30, well maybe today but tomorrow it might be 25 or 40 so in order to size your Arrays to hold the file data you will need to know how many lines of that actual raw data is contained within the CSV file (excluding Header, possible comments, and possible blank lines). The easiest way would be to just dump everything into separate ArrayList's and then convert them to their respective arrays later on be it String, int's, long's, double, whatever.

Counting file lines first so as to initialize Arrays:

One line of code can give you the number of lines contained within a supplied text file:

```<code>long count = Files.lines(Paths.get("C:\\MyDataFiles\\DataFile.csv")).count();
</code>```

In reality however, on its own the above code line does need to be enclosed within a try/catch block in case of a IO Exception so there is a wee bit more code than a single line. For a simple use case where the CSV file contains a Header Line and no Comment or Blank lines this could be all you need since all you would need to do is subtract one to eliminate the Header Line from the overall count for initializing your Arrays. Another minor issue with the above one-liner is the fact that it provides a count value in a Long Integer (long) data type. This is no good since Java Arrays will only accept Integer (int) values for initialization therefore the value obtained will need to be cast to int, for example:

```<code>String[] countries = new String[(int) count];
</code>```

and this is only good if count does not exceed the Integer.MAX_VALUE - 2 (2147483645). That's a lot of array elements so in general you wouldn't really have a problem with this but if are dealing with extremely large array initializations then you will also need to consider JVM Memory and running out of it.

Sometimes it's just nice to have a method that could be used for a multitude of different situations when getting the total number of raw data lines from a CSV (or other) text file. The provided method below is obviously more than a single line of code but it does provide a little more flexibility towards what to count in a file. As mentioned earlier there is the possibility of a Header Line. A Header line is very common in CSV files and it is usually the first line within the file but this may not always be the case. The Header line could be preceded with a Comment Line of even a Blank Line. The Header line however should always be the first line before the raw data lines. Here is an example of a possible CSV file:

Example CSV file contents:

```<code># Units Summary Report
# End Date: May 27, 2019

Country,TimeScale,Vendor,Units
Czech Republic,2010 Q3,Fujitsu Siemens,2924.742032
Slovakia,2010 Q4,Dell,2525r.011404
Slovakia,2010 Q4,Lenovo,2648.973238
Czech Republic,2010 Q3,ASUS,1323.507139
Czech Republic,2010 Q4,Apple,266.7584542
</code>```

The first two lines are Comment Lines and Comment Lines always begin with either a Hash (#) character or a Semicolon (;). These lines are to be ignored when read.

The third line is a Blank Line and serves absolutely no purpose other than aesthetics (easier on the eyes I suppose). These lines are also to be ignored.

The fourth line which is directly above the raw data lines is the Header Line. This line may or may not be contained within a CSV file. Its purpose is to provide the Column Names for the data records contained on each raw data line. This line can be read (if it exists) to acquire record field (column) names.

The remaining lines within the CSV file are Raw Data Lines otherwise considered data records. Each line is a complete record and each delimited element of that record is considered a data field value. These are the lines you want to count so as to initialize your different Arrays. Here is a method that allows you to do that:

The fileLinesCount() Method:

```<code>/**
 * Counts the number of lines within the supplied Text file. Which lines are
 * counted depends upon the optional arguments supplied. By default, all
 * file lines are counted.<br><br>
 *
 * @param filePath     (String) The file path and name of file (with
 *                     extension) to count lines in.<br>
 *
 * @param countOptions (Optional - Boolean) Three Optional Parameters. If an
 *                     optional argument is provided then the preceeding
 *                     optional argument MUST also be provided (be it true
 *                     or false):```
 *
 *      ignoreHeader    - Default is false. If true is passed then a value of
 *                        one (1) is subtracted from the sum of lines detected.
 *                        You must know for a fact that a header exists before
 *                        passing true to this optional parameter.
 *
 *      ignoreComments  - Default is false. If true is passed then comment lines
 *                        are ignored from the count. Only file lines (after being
 *                        trimmed) which start with either a semicolon (;) or a
 *                        hash (#) character are considered a comment line. These
 *                        characters are typical for comment lines in CSV files and
 *                        many other text file formats.
 *
 *      ignoreBlanks    - Default is false. If true is passed then file lines
 *                        which contain nothing after they are trimmed is ignored
 *                        in the count.
 *
 *                        When a line is Trimmed:
 *                        If the String_Object represents an empty character
 *                        sequence then reference to this String_Object is
 *                        returned. If both the first & last character of the
 *                        String_Object have codes greater than unicode ‘\u0020’
 *                        (the space character) then reference to this String_Object
 *                        is returned. When there is no character with a code
 *                        greater than unicode ‘\u0020’ (the space character)
 *                        then an empty string is created and returned.
 *
 *                        As an example, a trimmed line removes leading and
 *                        trailing whitespaces, tabs, Carriage Returns, and
 *                        Line Feeds.```
 *
 * @return (Long) The number of lines contained within the supplied text
 *         file.
 */
public long fileLinesCount(final String filePath, final boolean... countOptions) {
    // Defaults for optional parameters.
    final boolean ignoreHeader = (countOptions.length >= 1 ? countOptions[0] : false);
    // Only strings in lines that start with ';' or '#' are considered comments.
    final boolean ignoreComments = (countOptions.length >= 2 ? countOptions[1] : false);
    // All lines that when trimmed contain nothing (null string).
    final boolean ignoreBlanks = (countOptions.length >= 3 ? countOptions[2] : false);
    long count = 0;   // lines Count variable to hold the number of lines.

    // Gather supplied arguments for optional parameters
    try {
        if (ignoreBlanks) {
            // Using lambda along with Ternary Operator
            count = Files.lines(Paths.get(filePath)).filter(line -> (ignoreComments
                    ? (!line.trim().startsWith(";") && !line.trim().startsWith("#"))
                    && line.trim().length() > 0 : line.trim().length() > 0)).count();
            if (ignoreHeader) {
                count--;
            }
            return count;
        }

        if (ignoreComments) {
            // Using lambda along with Ternary Operator
            count = Files.lines(Paths.get(filePath)).filter(line -> (ignoreBlanks ? line.trim().length() > 0
                    && (!line.trim().startsWith(";") && !line.trim().startsWith("#"))
                    : (!line.trim().startsWith(";") && !line.trim().startsWith("#")))).count();
            if (ignoreHeader) {
                count--;
            }
            return count;
        }

        else {
            count = Files.lines(Paths.get(filePath)).count();
            if (ignoreHeader) {
                count--;
            }
        }

    }
    catch (IOException ex) {
        Logger.getLogger("fileLinesCount() Method Error!").log(Level.SEVERE, null, ex);
    }
    return count;
}
</code>```

Filling the Parallel Arrays:

Now it time to create a method to fill the desired Arrays and by looking at the data file it look like you need three String type arrays and one double type Array. You may want to make these instance or Class member variables:

```<code>// Instance (Class Member) variables:
String[] country;
String[] timeScale;
String[] vendor;
double[] units;
</code>```

then  for filling these arrays we would use an method like this:

```<code>/**
 * Fills the 4 class member array variables country[], timeScale[], vendor[],
 * and units[] with data obtained from the supplied CSV data file.<br><br>
 *
 * @param filePath (String) Full Path and file name of the CSV data file.<br>
 *
 * @param fileHasHeader (Boolean) Either true or false. Supply true if the CSV
 * file does contain a Header and false if it does not.
 */
public void fillDataArrays(String filePath, boolean fileHasHeader) {
    long dataCount = fileLinesCount(filePath, fileHasHeader, true, true);

    /* Java Arrays will not accept the long data type for sizing
       therefore we cast to int.   */
    country = new String[(int) dataCount];
    timeScale = new String[(int) dataCount];
    vendor = new String[(int) dataCount];
    units = new double[(int) dataCount];
    int lineCounter = 0;    // counts all lines contained within the supplied text file

    try (Scanner reader = new Scanner(new File("DataFile.txt"))) {
        int indexCounter = 0;
        while (reader.hasNextLine()) {
            lineCounter++;
            String line = reader.nextLine().trim();
            // Skip comment and blank file lines.
            if (line.startsWith(";") || line.startsWith("#") || line.equals("")) {
                continue;
            }
            if (indexCounter == 0 && fileHasHeader) {
                /* Since we are skipping the header right away we
                   now no longer need the fileHasHeader flag.   */
                fileHasHeader = false;
                continue;   // Skip the first line of data since it's a header
            }
            /* Split the raw data line based on a comma (,) delimiter.
               The Regular Expression (\\s{0,},\\s{0,}") ensures that
               it doesn't matter how many spaces (if any at all) are
               before OR after the comma, the split removes those
               unwanted spaces, even tabs are removed if any.
            */
            String[] splitLine = line.split("\\s{0,},\\s{0,}");
            country[indexCounter] = splitLine[0];
            timeScale[indexCounter] = splitLine[1];
            vendor[indexCounter] = splitLine[2];
            /* The Regular Expression ("-?\\d+(\\.\\d+)?") below ensures
               that the value contained within what it to be the Units
               element of the split array is actually a string representation
               of a signed or unsigned integer or double/float numerical value.
            */
            if (splitLine[3].matches("-?\\d+(\\.\\d+)?")) {
                units[indexCounter] = Double.parseDouble(splitLine[3]);
            }
            else {
                JOptionPane.showMessageDialog(this, "<html>An invalid Units value (<b><font color=blue>" +
                        splitLine[3] + "</font></b>) has been detected<br>in data file line number <b><font " +
                        "color=red>" + lineCounter + "</font></b>. A value of <b>0.0</b> has been applied<br>to " +
                        "the Units Array to replace the data provided on the data<br>line which consists of: " +
                        "<br><br><b><center>" + line + "</center></b>.", "Invalid Units Value Detected!",
                        JOptionPane.WARNING_MESSAGE);
                units[indexCounter] = 0.0d;
            }
            indexCounter++;
        }
    }
    catch (IOException ex) {
        Logger.getLogger("fillDataArrays() ethod Error!").log(Level.SEVERE, null, ex);
    }
}
</code>```

To get the ball rolling just run the following code:

```<code>/// Fill the Arrays with data.
fillDataArrays("DataFile.txt", true);

// Display the filled Arrays.
System.out.println(Arrays.toString(country));
System.out.println(Arrays.toString(timeScale));
System.out.println(Arrays.toString(vendor));
System.out.println(Arrays.toString(units));
</code>```

Body:
Values are separated with comma, following format:

Country,Timescale,Vendor,Units
Africa,2010 Q3,Fujitsu Siemens,2924.742632

I want to make array for every value. How can I do it?

I tried many things, code below:

BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {

    br = new BufferedReader(new FileReader(csvFile));
    while ((line = br.readLine()) != null) {
        String[] country = line.split(cvsSplitBy);
        country[0] +=",";
        String[] Krajina = country[0].split(",");

Body:
What you appear to be talking about is utilizing what is otherwise known as Parallel Arrays and is generally a bad idea in this particular use case since it can be prone to OutOfBounds Exceptions later on down the road. A better solution would be to utilize a Two Dimensional (2D) Array or an ArrayList. Never the less, parallel arrays it is:

You say an array size of 30, well maybe today but tomorrow it might be 25 or 40 so in order to size your Arrays to hold the file data you will need to know how many lines of that actual raw data is contained within the CSV file (excluding Header, possible comments, and possible blank lines). The easiest way would be to just dump everything into separate ArrayList's and then convert them to their respective arrays later on be it String, int's, long's, double, whatever.

Counting file lines first so as to initialize Arrays:

One line of code can give you the number of lines contained within a supplied text file:

long count = Files.lines(Paths.get("C:\\MyDataFiles\\DataFile.csv")).count();

In reality however, on its own the above code line does need to be enclosed within a try/catch block in case of a IO Exception so there is a wee bit more code than a single line. For a simple use case where the CSV file contains a Header Line and no Comment or Blank lines this could be all you need since all you would need to do is subtract one to eliminate the Header Line from the overall count for initializing your Arrays. Another minor issue with the above one-liner is the fact that it provides a count value in a Long Integer (long) data type. This is no good since Java Arrays will only accept Integer (int) values for initialization therefore the value obtained will need to be cast to int, for example:

String[] countries = new String[(int) count];

and this is only good if count does not exceed the Integer.MAX_VALUE - 2 (2147483645). That's a lot of array elements so in general you wouldn't really have a problem with this but if are dealing with extremely large array initializations then you will also need to consider JVM Memory and running out of it.

Sometimes it's just nice to have a method that could be used for a multitude of different situations when getting the total number of raw data lines from a CSV (or other) text file. The provided method below is obviously more than a single line of code but it does provide a little more flexibility towards what to count in a file. As mentioned earlier there is the possibility of a Header Line. A Header line is very common in CSV files and it is usually the first line within the file but this may not always be the case. The Header line could be preceded with a Comment Line of even a Blank Line. The Header line however should always be the first line before the raw data lines. Here is an example of a possible CSV file:

Example CSV file contents:

# Units Summary Report
# End Date: May 27, 2019

Country,TimeScale,Vendor,Units
Czech Republic,2010 Q3,Fujitsu Siemens,2924.742032
Slovakia,2010 Q4,Dell,2525r.011404
Slovakia,2010 Q4,Lenovo,2648.973238
Czech Republic,2010 Q3,ASUS,1323.507139
Czech Republic,2010 Q4,Apple,266.7584542

The first two lines are Comment Lines and Comment Lines always begin with either a Hash (#) character or a Semicolon (;). These lines are to be ignored when read.

The third line is a Blank Line and serves absolutely no purpose other than aesthetics (easier on the eyes I suppose). These lines are also to be ignored.

The fourth line which is directly above the raw data lines is the Header Line. This line may or may not be contained within a CSV file. Its purpose is to provide the Column Names for the data records contained on each raw data line. This line can be read (if it exists) to acquire record field (column) names.

The remaining lines within the CSV file are Raw Data Lines otherwise considered data records. Each line is a complete record and each delimited element of that record is considered a data field value. These are the lines you want to count so as to initialize your different Arrays. Here is a method that allows you to do that:

The fileLinesCount() Method:

/**
 * Counts the number of lines within the supplied Text file. Which lines are
 * counted depends upon the optional arguments supplied. By default, all
 * file lines are counted.<br><br>
 *
 * @param filePath     (String) The file path and name of file (with
 *                     extension) to count lines in.<br>
 *
 * @param countOptions (Optional - Boolean) Three Optional Parameters. If an
 *                     optional argument is provided then the preceeding
 *                     optional argument MUST also be provided (be it true
 *                     or false):<pre>
 *
 *      ignoreHeader    - Default is false. If true is passed then a value of
 *                        one (1) is subtracted from the sum of lines detected.
 *                        You must know for a fact that a header exists before
 *                        passing <b>true</b> to this optional parameter.
 *
 *      ignoreComments  - Default is false. If true is passed then comment lines
 *                        are ignored from the count. Only file lines (after being
 *                        trimmed) which <b>start with</b> either a semicolon (;) or a
 *                        hash (#) character are considered a comment line. These
 *                        characters are typical for comment lines in CSV files and
 *                        many other text file formats.
 *
 *      ignoreBlanks    - Default is false. If true is passed then file lines
 *                        which contain nothing after they are trimmed is ignored
 *                        in the count.
 *
 *                        <u>When a line is Trimmed:</u>
 *                        If the String_Object represents an empty character
 *                        sequence then reference to this String_Object is
 *                        returned. If both the first & last character of the
 *                        String_Object have codes greater than unicode ‘\u0020’
 *                        (the space character) then reference to this String_Object
 *                        is returned. When there is no character with a code
 *                        greater than unicode ‘\u0020’ (the space character)
 *                        then an empty string is created and returned.
 *
 *                        As an example, a trimmed line removes leading and
 *                        trailing whitespaces, tabs, Carriage Returns, and
 *                        Line Feeds.</pre>
 *
 * @return (Long) The number of lines contained within the supplied text
 *         file.
 */
public long fileLinesCount(final String filePath, final boolean... countOptions) {
    // Defaults for optional parameters.
    final boolean ignoreHeader = (countOptions.length >= 1 ? countOptions[0] : false);
    // Only strings in lines that start with ';' or '#' are considered comments.
    final boolean ignoreComments = (countOptions.length >= 2 ? countOptions[1] : false);
    // All lines that when trimmed contain nothing (null string).
    final boolean ignoreBlanks = (countOptions.length >= 3 ? countOptions[2] : false);
    long count = 0;   // lines Count variable to hold the number of lines.

    // Gather supplied arguments for optional parameters
    try {
        if (ignoreBlanks) {
            // Using lambda along with Ternary Operator
            count = Files.lines(Paths.get(filePath)).filter(line -> (ignoreComments
                    ? (!line.trim().startsWith(";") && !line.trim().startsWith("#"))
                    && line.trim().length() > 0 : line.trim().length() > 0)).count();
            if (ignoreHeader) {
                count--;
            }
            return count;
        }

        if (ignoreComments) {
            // Using lambda along with Ternary Operator
            count = Files.lines(Paths.get(filePath)).filter(line -> (ignoreBlanks ? line.trim().length() > 0
                    && (!line.trim().startsWith(";") && !line.trim().startsWith("#"))
                    : (!line.trim().startsWith(";") && !line.trim().startsWith("#")))).count();
            if (ignoreHeader) {
                count--;
            }
            return count;
        }

        else {
            count = Files.lines(Paths.get(filePath)).count();
            if (ignoreHeader) {
                count--;
            }
        }

    }
    catch (IOException ex) {
        Logger.getLogger("fileLinesCount() Method Error!").log(Level.SEVERE, null, ex);
    }
    return count;
}

Filling the Parallel Arrays:

Now it time to create a method to fill the desired Arrays and by looking at the data file it look like you need three String type arrays and one double type Array. You may want to make these instance or Class member variables:

// Instance (Class Member) variables:
String[] country;
String[] timeScale;
String[] vendor;
double[] units;

then  for filling these arrays we would use an method like this:

/**
 * Fills the 4 class member array variables country[], timeScale[], vendor[],
 * and units[] with data obtained from the supplied CSV data file.<br><br>
 *
 * @param filePath (String) Full Path and file name of the CSV data file.<br>
 *
 * @param fileHasHeader (Boolean) Either true or false. Supply true if the CSV
 * file does contain a Header and false if it does not.
 */
public void fillDataArrays(String filePath, boolean fileHasHeader) {
    long dataCount = fileLinesCount(filePath, fileHasHeader, true, true);

    /* Java Arrays will not accept the long data type for sizing
       therefore we cast to int.   */
    country = new String[(int) dataCount];
    timeScale = new String[(int) dataCount];
    vendor = new String[(int) dataCount];
    units = new double[(int) dataCount];
    int lineCounter = 0;    // counts all lines contained within the supplied text file

    try (Scanner reader = new Scanner(new File("DataFile.txt"))) {
        int indexCounter = 0;
        while (reader.hasNextLine()) {
            lineCounter++;
            String line = reader.nextLine().trim();
            // Skip comment and blank file lines.
            if (line.startsWith(";") || line.startsWith("#") || line.equals("")) {
                continue;
            }
            if (indexCounter == 0 && fileHasHeader) {
                /* Since we are skipping the header right away we
                   now no longer need the fileHasHeader flag.   */
                fileHasHeader = false;
                continue;   // Skip the first line of data since it's a header
            }
            /* Split the raw data line based on a comma (,) delimiter.
               The Regular Expression (\\s{0,},\\s{0,}") ensures that
               it doesn't matter how many spaces (if any at all) are
               before OR after the comma, the split removes those
               unwanted spaces, even tabs are removed if any.
            */
            String[] splitLine = line.split("\\s{0,},\\s{0,}");
            country[indexCounter] = splitLine[0];
            timeScale[indexCounter] = splitLine[1];
            vendor[indexCounter] = splitLine[2];
            /* The Regular Expression ("-?\\d+(\\.\\d+)?") below ensures
               that the value contained within what it to be the Units
               element of the split array is actually a string representation
               of a signed or unsigned integer or double/float numerical value.
            */
            if (splitLine[3].matches("-?\\d+(\\.\\d+)?")) {
                units[indexCounter] = Double.parseDouble(splitLine[3]);
            }
            else {
                JOptionPane.showMessageDialog(this, "<html>An invalid Units value (<b><font color=blue>" +
                        splitLine[3] + "</font></b>) has been detected<br>in data file line number <b><font " +
                        "color=red>" + lineCounter + "</font></b>. A value of <b>0.0</b> has been applied<br>to " +
                        "the Units Array to replace the data provided on the data<br>line which consists of: " +
                        "<br><br><b><center>" + line + "</center></b>.", "Invalid Units Value Detected!",
                        JOptionPane.WARNING_MESSAGE);
                units[indexCounter] = 0.0d;
            }
            indexCounter++;
        }
    }
    catch (IOException ex) {
        Logger.getLogger("fillDataArrays() ethod Error!").log(Level.SEVERE, null, ex);
    }
}

To get the ball rolling just run the following code:

/// Fill the Arrays with data.
fillDataArrays("DataFile.txt", true);

// Display the filled Arrays.
System.out.println(Arrays.toString(country));
System.out.println(Arrays.toString(timeScale));
System.out.println(Arrays.toString(vendor));
System.out.println(Arrays.toString(units));


问:
Implementation of String.prototype.startsWith in ClojureScript
I need to convert this Javascript code into ClojureScript. I'm having some trouble with the this keyword.

Here's my JS:

```<code>if (!String.prototype.startsWith) {
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.indexOf(searchString, position) === position;
  };
}
</code>```

I'm getting a Object doesn't support property or method 'startsWith' error with the Google Closure compiler in advanced mode so I need to add this code. (IE 11)

答:
Try this ClojureScript code:</p>

```<code>(when (not (.. js/String -prototype -startsWith))
  (set!
    (.. js/String -prototype -startsWith)
    (fn [searchString position]
      (set! position (or position 0))
      (= (this-as this (.indexOf this) searchString position) position))))
</code>```

Body:
I need to convert this Javascript code into ClojureScript. I'm having some trouble with the this keyword.

Here's my JS:

if (!String.prototype.startsWith) {
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.indexOf(searchString, position) === position;
  };
}

I'm getting a Object doesn't support property or method 'startsWith' error with the Google Closure compiler in advanced mode so I need to add this code. (IE 11)

Body:
Try this ClojureScript code:

(when (not (.. js/String -prototype -startsWith))
  (set!
    (.. js/String -prototype -startsWith)
    (fn [searchString position]
      (set! position (or position 0))
      (= (this-as this (.indexOf this) searchString position) position))))


问:
when does useEffect fire in componentWillUnmount?
I read below statement in a blog, it says something like this

```<code>useEffect(() => {
  API.getUser(userId);
}, [userId]);
</code>```

Optionally the second parameter can also just be an empty array, in
  this case it will only execute on componentDidMount and
  componentWillUnmount and the effect won't run on componentDidUpdate.

Does the API.getUser got executed when the component got unmounted (componentWillUnmount)? as I know componentWillUnmount trigger when you go from page A to page B. I'm confused now, for me, above code act like componentDidMount, because userId will change from undefined to id once.

答:
You can return clean up function from useEffect which will run before unMount

```<code>useEffect(() => {
  const subscription = props.source.subscribe(); // this will fire at after did Mount/ didUpdate
  return () => {
    // Clean up the subscription
    subscription.unsubscribe(); // this will afire at willUnmount
  };
});
</code>```

If you pass empty array as second parameter.

```<code>useEffect(() => {
  const subscription = props.source.subscribe(); // this run only after first rnede i.e componentDidmount
  return () => {
    // Clean up the subscription
    subscription.unsubscribe(); // this will afire at willUnmount ie componentWillUnmount
  };
}, []);
</code>```

Body:
I read below statement in a blog, it says something like this

useEffect(() => {
  API.getUser(userId);
}, [userId]);

Optionally the second parameter can also just be an empty array, in
  this case it will only execute on componentDidMount and
  componentWillUnmount and the effect won't run on componentDidUpdate.

Does the API.getUser got executed when the component got unmounted (componentWillUnmount)? as I know componentWillUnmount trigger when you go from page A to page B. I'm confused now, for me, above code act like componentDidMount, because userId will change from undefined to id once.

Body:
You can return clean up function from useEffect which will run before unMount

useEffect(() => {
  const subscription = props.source.subscribe(); // this will fire at after did Mount/ didUpdate
  return () => {
    // Clean up the subscription
    subscription.unsubscribe(); // this will afire at willUnmount
  };
});

If you pass empty array as second parameter.

useEffect(() => {
  const subscription = props.source.subscribe(); // this run only after first rnede i.e componentDidmount
  return () => {
    // Clean up the subscription
    subscription.unsubscribe(); // this will afire at willUnmount ie componentWillUnmount
  };
}, []);


问:
Remote Desktop Connection with Custom Credential Provider
I have developed a custom credential provider using the SampleWrapExistingCredentialProvider from VistaCredentialProviderSamples. The credential provider has a filter implemented that filters all other credential providers and I see just my credential provider at the time of logon. The issue is that if we connect to it using remote desktop connection, the username/password are not passed from windows RDP client to the Credential provider and I have to enter it again when RDP session opens (unlike the behavior with default provider)

I am trying to explore which part of the code handles this scenario that the credential provider accepts the username/password from remote desktop client and does not ask again. Attached is the screenshot of my credential provider after providing successful credentials on the RDP client. After I click this icon of my credential provider, I am shown the credential provider tile that asking again for the username and password. Any help would be highly appreciated on how to receive credentials from RDP client.

I have returned S_OK for CREDUI. My SetUsageScenario is as follows:

```<code>HRESULT CSampleProvider::SetUsageScenario(
CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,
DWORD dwFlags
)
{
    HRESULT hr;

// Create the password credential provider and query its interface for an
// ICredentialProvider we can use. Once it's up and running, ask it about the
// usage scenario being provided.
IUnknown *pUnknown = NULL;
hr = ::CoCreateInstance(CLSID_PasswordCredentialProvider, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pUnknown));
if (SUCCEEDED(hr))
{
    hr = pUnknown->QueryInterface(IID_PPV_ARGS(&(_pWrappedProvider)));
    if (SUCCEEDED(hr))
    {
        hr = _pWrappedProvider->SetUsageScenario(cpus, dwFlags);
        switch (cpus)
        {
        case CPUS_LOGON:
        case CPUS_UNLOCK_WORKSTATION:
        case CPUS_CREDUI:
        {
            hr = S_OK;
            break;
        }
        case CPUS_CHANGE_PASSWORD:
        default:
            hr = E_INVALIDARG;
            break;
        }
    }
}
if (FAILED(hr))
{
    if (_pWrappedProvider != NULL)
    {
        _pWrappedProvider->Release();
        _pWrappedProvider = NULL;
    }
}

return hr;
}
</code>```

答:
According to official documentationhttps: RDC and Custom Credential Providers

If the user connected with a non-Microsoft credential provider, then
  you will be prompted on the terminal server to enter credentials again
  (twice).  If NLA is not enabled, then despite entering using an
  unsupported credential provider on the client prior to the connection,
  the user will still be connected.  You will be left at the logon
  screen, where you can use any credential provider that is supported
  for local authentication.  There’s no way to avoid the two
  authentications when using unsupported credential providers.

Having said that, if you have your own credential providers and you
  try to do a remote desktop connection to a Vista box (having this
  Credential provider) then you would need to log-in twice. This is an
  expected behavior and it is by design and there is no legitimate way
  to avoid it.

Body:
I have developed a custom credential provider using the SampleWrapExistingCredentialProvider from VistaCredentialProviderSamples. The credential provider has a filter implemented that filters all other credential providers and I see just my credential provider at the time of logon. The issue is that if we connect to it using remote desktop connection, the username/password are not passed from windows RDP client to the Credential provider and I have to enter it again when RDP session opens (unlike the behavior with default provider)

I am trying to explore which part of the code handles this scenario that the credential provider accepts the username/password from remote desktop client and does not ask again. Attached is the screenshot of my credential provider after providing successful credentials on the RDP client. After I click this icon of my credential provider, I am shown the credential provider tile that asking again for the username and password. Any help would be highly appreciated on how to receive credentials from RDP client.

I have returned S_OK for CREDUI. My SetUsageScenario is as follows:

HRESULT CSampleProvider::SetUsageScenario(
CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,
DWORD dwFlags
)
{
    HRESULT hr;

// Create the password credential provider and query its interface for an
// ICredentialProvider we can use. Once it's up and running, ask it about the
// usage scenario being provided.
IUnknown *pUnknown = NULL;
hr = ::CoCreateInstance(CLSID_PasswordCredentialProvider, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pUnknown));
if (SUCCEEDED(hr))
{
    hr = pUnknown->QueryInterface(IID_PPV_ARGS(&(_pWrappedProvider)));
    if (SUCCEEDED(hr))
    {
        hr = _pWrappedProvider->SetUsageScenario(cpus, dwFlags);
        switch (cpus)
        {
        case CPUS_LOGON:
        case CPUS_UNLOCK_WORKSTATION:
        case CPUS_CREDUI:
        {
            hr = S_OK;
            break;
        }
        case CPUS_CHANGE_PASSWORD:
        default:
            hr = E_INVALIDARG;
            break;
        }
    }
}
if (FAILED(hr))
{
    if (_pWrappedProvider != NULL)
    {
        _pWrappedProvider->Release();
        _pWrappedProvider = NULL;
    }
}

return hr;
}


问:
Escape Character in SQL Server
I want to use quotation with escape character. How can I do to avoid the following error when one has a special character?

Unclosed quotation mark after the character string.

答: To keep the code easy to read, you can use square brackets [] to quote the string containing ' or vice versa .

Title: Escape Character in SQL Server


问:
best practise: Implementation of iAds to iPhone
I'm trying to integrate iAds to iPhone app. It makes me very confusing.
my app got many view controllers with uitableviews.

Should I integrate iAds at every view controller or
should I add it in mainwindow.xib (i add iAds codes to AppDelegate.h .m) or
should I create iAdsViewcontroller.h .m & .xib?

if I add iAds to mianwindow.xib, how do i handle delegates like bannerViewDidLoadAd (need to resize uitableview according to bannerview is visibie or not).

If i integrate at every view controller, banner would be switching along with the app views. I read somewhere  if the app doesn't show an Ad for at least 30 seconds, it will lose ecpm.

Any thoughts will be appreciated... =)

答: Apple iAd Documentation Best Practices</p>

Body: Apple iAd Documentation Best Practices


问:
How to execute a function in child component when (change) on a select in the parent component happens
I have child component with a function that I want to call once the (change) event gets triggered on a select in the parent component. Is this possible?</p>

答:
Yes, you can use @ViewChild

Try this:

Parent Component:

HTML:

```<code><select (change)="selectDropdownChange()">
    <option >...</option>
</select>

<child-comp #childRef></child-comp>
</code>```

TS:

@ViewChild('childRef') childRef: ChildComp;

```<code>selectDropdownChange() {
    this.childRef.childFunction();
}
</code>```

Body:
Yes, you can use @ViewChild

Try this:

Parent Component:

HTML:

<select (change)="selectDropdownChange()">
    <option >...</option>
</select>

<child-comp #childRef></child-comp>

TS:

@ViewChild('childRef') childRef: ChildComp;

selectDropdownChange() {
    this.childRef.childFunction();
}


问:
Product based gallery, dynamic title not working properly
This is the link of the site: https://www.silvanacasciaro.it/
The gallery is the one with the shoes and bags after the 3 round images of the collections, next to "i nostri brand". The problem is that whatever image you click on, the little title on the top left shows the name of the first image no matter what and starts from there, instead of showing the actual name of the photo a clicked on. Any help would be greatly appreciated.

Here is the html:

```<code>    <div id="blueimp-gallery" class="blueimp-gallery">
        <!-- The container for the modal slides -->
        <div class="slides"></div>
        <!-- Controls for the borderless lightbox -->
        <h3 class="title"></h3>
        <!-- <p class="description"></p> -->
        <a class="prev">‹</a>
        <a class="next">›</a>
        <a class="close">×</a>
        <a class="play-pause"></a>
        <ol class="indicator"></ol>
        <!-- The modal dialog, which will be used to wrap the lightbox content -->
        <div class="modal fade">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" aria-hidden="true">×</button>
                        <h4 class="modal-title"></h4>
                    </div>
                    <div class="modal-body next"></div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default pull-left prev">
                            <i class="glyphicon glyphicon-chevron-left"></i>
                            Previous
                        </button>
                        <button type="button" class="btn btn-primary next">
                            Next
                            <i class="glyphicon glyphicon-chevron-right"></i>
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</code>```

And here is the js:

```<code>
    <script src="//blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js"></script>
    <script src="<?php echo get_stylesheet_directory_uri(); ?>/js/bootstrap-image-gallery.min.js"></script>

    <script>
    document.getElementById('links').onclick = function (event) {
          event = event || window.event;
          var target = event.target || event.srcElement,
            link = target.src ? target.parentNode : target,
            options = {
              index: link, event: event,
              onclose: function () {
                        // Callback function executed when the Gallery is about to be closed.
                        jQuery('body').css('overflow','auto !important');
                    },
              onslide: function (index, slide) {
                self = this;
                var initializeAdditional = function (index, data, klass, self) {
                  var text = self.list[index].getAttribute(data),
                    node = self.container.find(klass);
                  node.empty();
                  if (text) {
                    node[0].appendChild(document.createTextNode(text));
                  }
                };

                initializeAdditional(index, 'data-title', '.title', self);
              }
            },
            links = this.getElementsByTagName('a');
          blueimp.Gallery(links, options);

    };
    </script>
</code>```

答:
The problem is getting parent a element.
In this line you are trying to get parent a element:

```<code>link = target.src ? target.parentNode : target,
</code>```

But actually it gets

```<code><div class="image_wrapper">
<img class="" alt="Tronchetto | Silvana Casciaro" src="https://www.silvanacasciaro.it/wp-content/uploads/2019/04/CHIARINI-BOLOGNA-tronchetto.jpg">
</div>
</code>```

The only thing you need to do to solve this issue is replacing target.parentNode with target.parentNode.parentNode and to get this:

```<code>link = target.src ? target.parentNode.parentNode : target,
</code>```

In that case variable "link" will get correct object and the code will start working:

```<code><a href="https://www.silvanacasciaro.it/wp-content/uploads/2019/05/LIU-JO-–-Zaino-Romantica2.jpg" data-title="Zaino Romantica" data-gallery="#blueimp-gallery" class="maggiori_info" title="Zaino Romantica">
      <div class="image_wrapper">
              <img class="" alt="Zaino Romantica | Silvana Casciaro" src="https://www.silvanacasciaro.it/wp-content/uploads/2019/05/LIU-JO-–-Zaino-Romantica2.jpg">
            </div><!--image_wrapper-->
       <h4 class="prod_title">Zaino Romantica</h4>
       <button class="btn btn-lg">Scopri</button>
     </a>
</code>```

p.s. Your code also has some another issues and you may need to debug it in your browser console.

Body:
This is the link of the site: https://www.silvanacasciaro.it/
The gallery is the one with the shoes and bags after the 3 round images of the collections, next to "i nostri brand". The problem is that whatever image you click on, the little title on the top left shows the name of the first image no matter what and starts from there, instead of showing the actual name of the photo a clicked on. Any help would be greatly appreciated.

Here is the html:

        ‹
        ›
        ×

                        <button type="button" class="close" aria-hidden="true">×</button>

                        <button type="button" class="btn btn-default pull-left prev">

                            Previous
                        </button>
                        <button type="button" class="btn btn-primary next">
                            Next

                        </button>

And here is the js:

Body:
The problem is getting parent a element.
In this line you are trying to get parent a element:

link = target.src ? target.parentNode : target,

But actually it gets

<div class="image_wrapper">
<img class="" alt="Tronchetto | Silvana Casciaro" src="https://www.silvanacasciaro.it/wp-content/uploads/2019/04/CHIARINI-BOLOGNA-tronchetto.jpg">
</div>

The only thing you need to do to solve this issue is replacing target.parentNode with target.parentNode.parentNode and to get this:

link = target.src ? target.parentNode.parentNode : target,

In that case variable "link" will get correct object and the code will start working:

<a href="https://www.silvanacasciaro.it/wp-content/uploads/2019/05/LIU-JO-–-Zaino-Romantica2.jpg" data-title="Zaino Romantica" data-gallery="#blueimp-gallery" class="maggiori_info" title="Zaino Romantica">
      <div class="image_wrapper">
              <img class="" alt="Zaino Romantica | Silvana Casciaro" src="https://www.silvanacasciaro.it/wp-content/uploads/2019/05/LIU-JO-–-Zaino-Romantica2.jpg">
            </div><!--image_wrapper-->
       <h4 class="prod_title">Zaino Romantica</h4>
       <button class="btn btn-lg">Scopri</button>
     </a>

p.s. Your code also has some another issues and you may need to debug it in your browser console.


问:
how to filter array list of collection view which is in accessory view
//  I just want to filter array list which is shown in collection view cell when user enter text in the textfield.
    On textfield editing collection data will be sort and filter according to textfield input. In case of collection view has a data about states, If I input 'A' in textfield, all collection data will be sort and display all state names starting with alphabet 'A'. Please tell me logic for this.

ios iphone

here is the link of my project ---- https://drive.google.com/drive/folders/1d56PWO2j6YcDU2AJyCseZC16dfUeV7Bd?usp=sharing //

ViewController.swift

```<code>import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        if let customView = Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)?.first as? CustomView {
            self.textField.inputAccessoryView = customView
        }
    }
}

class CustomView: UIView, UICollectionViewDataSource {
    @IBOutlet weak var collectionView: UICollectionView!

    let words = ["abscind","downwind","headwind","lind","rescind","sind","skinned","tailwind","thin-skinned","tinned","twinned","upwind","whirlwind","wind"]

    override func awakeFromNib() {
        super.awakeFromNib()
        self.collectionView.register(UINib(nibName: "CustomCell", bundle: nil), forCellWithReuseIdentifier: "cell")
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.words.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
        cell.label.text = self.words[indexPath.row]
        return cell
    }
}

class CustomCell: UICollectionViewCell {
    @IBOutlet weak var label: UILabel!
}
</code>```

答:
You need to update your dataSource everytime there is a change in textField's text.

You can track the changes in textField's text using UITextFieldDelegate method - textField(_:shouldChangeCharactersIn:replacementString:)

I've taken 2 arrays:

1. arr: It will contain the whole content that you can show in collectionView

2. dataSourceArr: It will contain the filtered content from arr based on textField's text. Initially both the arrays will have same content.

```<code>class ViewController: UIViewController, UICollectionViewDataSource, UITextFieldDelegate {
    @IBOutlet weak var collectionView: UICollectionView!

    var arr = [String]() //Original Array
    var dataSourceArr = arr //Filtered array based on textField content

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataSourceArr.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        return cell
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        self.reload(textField)
        return true
    }

    func reload(_ textField: UITextField) {
        if let text = textField.text {
            dataSourceArr = self.arr.filter({ $0.hasPrefix(text) }).sorted()
            collectionView.reloadData()
        }
    }
}
</code>```

Body:
//  I just want to filter array list which is shown in collection view cell when user enter text in the textfield.
    On textfield editing collection data will be sort and filter according to textfield input. In case of collection view has a data about states, If I input 'A' in textfield, all collection data will be sort and display all state names starting with alphabet 'A'. Please tell me logic for this.

ios iphone

here is the link of my project ---- https://drive.google.com/drive/folders/1d56PWO2j6YcDU2AJyCseZC16dfUeV7Bd?usp=sharing //

ViewController.swift

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        if let customView = Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)?.first as? CustomView {
            self.textField.inputAccessoryView = customView
        }
    }
}

class CustomView: UIView, UICollectionViewDataSource {
    @IBOutlet weak var collectionView: UICollectionView!

    let words = ["abscind","downwind","headwind","lind","rescind","sind","skinned","tailwind","thin-skinned","tinned","twinned","upwind","whirlwind","wind"]

    override func awakeFromNib() {
        super.awakeFromNib()
        self.collectionView.register(UINib(nibName: "CustomCell", bundle: nil), forCellWithReuseIdentifier: "cell")
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.words.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
        cell.label.text = self.words[indexPath.row]
        return cell
    }
}

class CustomCell: UICollectionViewCell {
    @IBOutlet weak var label: UILabel!
}

Body:
You need to update your dataSource everytime there is a change in textField's text.

You can track the changes in textField's text using UITextFieldDelegate method - textField(_:shouldChangeCharactersIn:replacementString:)

I've taken 2 arrays:

1. arr: It will contain the whole content that you can show in collectionView

2. dataSourceArr: It will contain the filtered content from arr based on textField's text. Initially both the arrays will have same content.

class ViewController: UIViewController, UICollectionViewDataSource, UITextFieldDelegate {
    @IBOutlet weak var collectionView: UICollectionView!

    var arr = [String]() //Original Array
    var dataSourceArr = arr //Filtered array based on textField content

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataSourceArr.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        return cell
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        self.reload(textField)
        return true
    }

    func reload(_ textField: UITextField) {
        if let text = textField.text {
            dataSourceArr = self.arr.filter({ $0.hasPrefix(text) }).sorted()
            collectionView.reloadData()
        }
    }
}


问:
Iterable disjunction in LINQ
Let's assume I have an IQueryable collection, and list of some strings.

I can build query this way:

```<code>foreach (var somestring in somestrings)
{
     collection = collection.Where(col=>col.Property.Contains(somestring);
}
</code>```

which will produce following SQL query:

```<code>SELECT ...... FROM ..... WHERE
(Property LIKE '%something1%') AND
(Property LIKE '%something2%') AND
(Property LIKE '%something3%')
</code>```

Note, that WHERE clauses are connected with ANDs.

Is there way, to construct similar query, but connected with ORs ?

答:
You can use a PredicateBuilder like this. See SO for more.

Here you can connect queries with AND or OR.

```<code>IQueryable<Product> SearchProducts (params string[] keywords)
{
  var predicate = PredicateBuilder.False<Product>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or (p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);
}
</code>```

Sample taken from C# 7.0 in a Nutshell

I've used this successfully when implementing custom search fields

eg.

[red blue] -> searches for red AND blue

[red, blue] -> searches for red OR blue

Title: Iterable disjunction in LINQ

Body:
Let's assume I have an IQueryable collection, and list of some strings.

I can build query this way:

foreach (var somestring in somestrings)
{
     collection = collection.Where(col=>col.Property.Contains(somestring);
}

which will produce following SQL query:

SELECT ...... FROM ..... WHERE
(Property LIKE '%something1%') AND
(Property LIKE '%something2%') AND
(Property LIKE '%something3%')

Note, that WHERE clauses are connected with ANDs.

Is there way, to construct similar query, but connected with ORs ?

Body:
You can use a PredicateBuilder like this. See SO for more.

Here you can connect queries with AND or OR.

IQueryable<Product> SearchProducts (params string[] keywords)
{
  var predicate = PredicateBuilder.False<Product>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or (p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);
}

Sample taken from C# 7.0 in a Nutshell

I've used this successfully when implementing custom search fields

eg.

[red blue] -> searches for red AND blue

[red, blue] -> searches for red OR blue


问:
I want if user register successfully then user will come next time the registration will not be show for that user
Can you read my question let me know the solution on that.

I want if user register successfully then user will come next time the registration will not be show for that user.

Please help me to solve this issue.

Thank you.

答:
In the config/session.php file you you may specify the number of minutes that you wish the session to be allowed to remain idle before it expires.

```<code>[
    ...

    'lifetime' => 120, // change this to the desired number of minutes
    'expire_on_close' => false,

    ...
]
</code>```

One more thing you can do is implement the remember me feature that comes out of the box with a brand new installation of laravel. more info here: https://laravel.com/docs/5.8/authentication#remembering-users

Body:
In the config/session.php file you you may specify the number of minutes that you wish the session to be allowed to remain idle before it expires.

[
    ...

    'lifetime' => 120, // change this to the desired number of minutes
    'expire_on_close' => false,

    ...
]

One more thing you can do is implement the remember me feature that comes out of the box with a brand new installation of laravel. more info here: https://laravel.com/docs/5.8/authentication#remembering-users


问:
ReSharper Code Cleanup/Reformat Code feature vs Versioning Control Systems
ReSharper Code cleanup feature (with "reorder members" and "reformat code" enabled) is really great. You define a layout template using XML, then a simple key combination reorganizes your whole source file (or folder/project/solution) according to the rules you set in the template.

Anyway, do you think that could be a problem regarding VCS like subversion, cvs, git, etc. ? Is there a chance that it causes many undesired conflicts ?

Thank you.

答:
Yes, it will definitely cause problems.  In addition to creating conflicts that have to be manually resolved, when you check in a file that has been reformatted, the VCS will note almost every line as having been changed.  This will make it hard for you or a teammate to look back at the history and see what changed when.

That said, if everyone autoformats their code the same way (ie, you distribute that XML template to the team), then it might work well.  The problems really only come in when not everyone is doing the same thing.

OwnerDisplayName: Romain Verdier

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: pkaeding


问:
Elegant and maintainable way of populating Tree structures in c#
I have a Tree.

```<code>class TreeNode {
    public TreeNode(string name, string description) {
        Name = name;
        Description = description;
    }
    string Name { get; set; }
    string Description { get; set; }
    public List<TreeNode> Children = new List<TreeNode>();
}
</code>```

I would like to populate a large one for unit testing purposes. I would really like to keep stuff DRY.

Say for illustration purposes my tree has the following structure

```
Parent,desc
  Child 1, desc1
    Grandchild 1, desc1
  Child 2, desc2
```

How would you go about populating the tree in an elegant an maintainable way?

I find this code quite repetitious and error prone:

```<code>var parent = new TreeNode("Parent", "desc");
var child1 = new TreeNode("Child 1", "desc1");
var child2 = new TreeNode("Child 2", "desc2");
var grandchild1 = new TreeNode("Grandchild 1", "desc1");

parent.Children.Add(child1);
parent.Children.Add(child2);

child1.Children.Add(grandchild1);
</code>```

EDIT

I ended up doing the DSL approach:

A demo test lives here.

The implementation is here.

It uses a builder and a simple DSL.

答:
Nested construction could be a good option here. Good idea to not expose the list of children too.</p>

```<code>class Program
{
    static void Main(string[] args)
    {
        var parent =
            new TreeNode( "Parent", "desc", new TreeNode[] {
                new TreeNode( "Child 1", "desc1", new TreeNode[] {
                    new TreeNode( "Grandchild 1", "desc1" ) } ),
                new TreeNode( "Child 2", "desc2" ) } );
    }
}

class TreeNode
{
    public TreeNode(string name, string description, IEnumerable<TreeNode> children)
        : this(name, description)
    {
        _children.AddRange(children);
    }

    public TreeNode(string name, string description)
    {
        Name = name;
        Description = description;
    }

    public string Name { get; set; }
    public string Description { get; set; }

    public IEnumerable<TreeNode> Children
    {
        get
        {
            return _children.AsReadOnly();
        }

        set
        {
            _children.Clear();
            _children.AddRange(value);
        }
    }

    private List<TreeNode> _children = new List<TreeNode>();
}
</code>```

Body:
I have a Tree.

class TreeNode {
    public TreeNode(string name, string description) {
        Name = name;
        Description = description;
    }
    string Name { get; set; }
    string Description { get; set; }
    public List<TreeNode> Children = new List<TreeNode>();
}

I would like to populate a large one for unit testing purposes. I would really like to keep stuff DRY.

Say for illustration purposes my tree has the following structure

Parent,desc
  Child 1, desc1
    Grandchild 1, desc1
  Child 2, desc2

How would you go about populating the tree in an elegant an maintainable way?

I find this code quite repetitious and error prone:

var parent = new TreeNode("Parent", "desc");
var child1 = new TreeNode("Child 1", "desc1");
var child2 = new TreeNode("Child 2", "desc2");
var grandchild1 = new TreeNode("Grandchild 1", "desc1");

parent.Children.Add(child1);
parent.Children.Add(child2);

child1.Children.Add(grandchild1);

EDIT

I ended up doing the DSL approach:

A demo test lives here.

The implementation is here.

It uses a builder and a simple DSL.

Body:
Nested construction could be a good option here. Good idea to not expose the list of children too.

class Program
{
    static void Main(string[] args)
    {
        var parent =
            new TreeNode( "Parent", "desc", new TreeNode[] {
                new TreeNode( "Child 1", "desc1", new TreeNode[] {
                    new TreeNode( "Grandchild 1", "desc1" ) } ),
                new TreeNode( "Child 2", "desc2" ) } );
    }
}

class TreeNode
{
    public TreeNode(string name, string description, IEnumerable<TreeNode> children)
        : this(name, description)
    {
        _children.AddRange(children);
    }

    public TreeNode(string name, string description)
    {
        Name = name;
        Description = description;
    }

    public string Name { get; set; }
    public string Description { get; set; }

    public IEnumerable<TreeNode> Children
    {
        get
        {
            return _children.AsReadOnly();
        }

        set
        {
            _children.Clear();
            _children.AddRange(value);
        }
    }

    private List<TreeNode> _children = new List<TreeNode>();
}


问:
Service: No provider for Renderer2
Angular 4.2 with Typescript 2.3

I am refactoring a service that is responsible for creating a new script tag and adding it to the document.

Here is the old code:

```<code>loadScript(src:string){
    const script = document.createElement('script');
    document.body.appendChild(script);
    script.src = src;
}
</code>```

Now, I'd like to use the Renderer2 to avoid doing direct DOM manipulation. So I've injected what I need in my service and updated the code:

```<code>constructor(private renderer:Renderer2, @Inject(DOCUMENT) private document){}

loadScript(src:string){
    const script = this.renderer.createElement('script');
    this.renderer.appendChild(this.document.body,script);
    script.src = src;
}
</code>```

However, I run into this error:

Error: no provider for Renderer2!

The service belongs to a CoreModule whose only import is CommonModule from @angular/common

This plunkr demonstrates the problem

答:
I tried to implement this using render2, but in a service - leading to 'StaticInjectorError(AppModule)[Renderer2]'-Error, as injecting Renderer2-Instance seems to not be possible. Solution was to inject RendererFactory2 and manullay create the reference within the service, like:</p>

```<code>@Injectable({
  providedIn: 'root'
})
export class FgRendererService {
  /** Reference to render-instance */
  public renderer: Renderer2;
  /** CONSTRUCTOR */
  constructor(
    private _renderer: RendererFactory2
  ) {
    this.renderer = _renderer.createRenderer(null, null);
  }
  /** Add class to body-tag */
  addBodyClass( classToAdd: string ): void {
    this.renderer.addClass( document.body, classToAdd );
  }
  /** Remove class from body-tag */
  removeBodyClass( classToRemove: string ): void {
    this.renderer.removeClass( document.body, classToRemove );
  }
}
</code>```

Title: Service: No provider for Renderer2

Body:
Angular 4.2 with Typescript 2.3

I am refactoring a service that is responsible for creating a new script tag and adding it to the document.

Here is the old code:

loadScript(src:string){
    const script = document.createElement('script');
    document.body.appendChild(script);
    script.src = src;
}

Now, I'd like to use the Renderer2 to avoid doing direct DOM manipulation. So I've injected what I need in my service and updated the code:

constructor(private renderer:Renderer2, @Inject(DOCUMENT) private document){}

loadScript(src:string){
    const script = this.renderer.createElement('script');
    this.renderer.appendChild(this.document.body,script);
    script.src = src;
}

However, I run into this error:

Error: no provider for Renderer2!

The service belongs to a CoreModule whose only import is CommonModule from @angular/common

This plunkr demonstrates the problem

Body:
I tried to implement this using render2, but in a service - leading to 'StaticInjectorError(AppModule)[Renderer2]'-Error, as injecting Renderer2-Instance seems to not be possible. Solution was to inject RendererFactory2 and manullay create the reference within the service, like:

@Injectable({
  providedIn: 'root'
})
export class FgRendererService {
  /** Reference to render-instance */
  public renderer: Renderer2;
  /** CONSTRUCTOR */
  constructor(
    private _renderer: RendererFactory2
  ) {
    this.renderer = _renderer.createRenderer(null, null);
  }
  /** Add class to body-tag */
  addBodyClass( classToAdd: string ): void {
    this.renderer.addClass( document.body, classToAdd );
  }
  /** Remove class from body-tag */
  removeBodyClass( classToRemove: string ): void {
    this.renderer.removeClass( document.body, classToRemove );
  }
}


问:
Retrofit2 call.enqueue(new Callback<ServerResponse>() is not working in android 9 and crash the app without any Error in the logcat
I'm Parsing some data from the server by Retrofit2. In other versions of Android and emulator, it is working fine. But the problem is it is not working in Android 9 (Pie) and Android Oreo (8.1). For this reason, the app is going to crash every time I installed. Another problem is, it's not showing any Error in the Logcat. So what can be the solution?

By reading some blogs and Stack Overflow, I have tried by adding android:usesCleartextTraffic="true" in the AndroidManifest. I have also added the below file in the AndroidManifest.

```<code>android:networkSecurityConfig="@xml/network_security_config"
</code>```

where network_security_config file is

```<code><?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">116.203.27.235/</domain>
    </domain-config>
</network-security-config>
</code>```

Here is the request code I made:

```<code>ApiInterface api = retrofit.create(ApiInterface.class);
Call<ServerResponse> call = api.getServerResult(new String(encodeValue));

call.enqueue(new Callback<ServerResponse>() {
        @Override
        public void onResponse(@NonNull Call<ServerResponse> call, @NonNull Response<ServerResponse> response) {
            Log.i(TAG, "onResponse: " + response.message());
            progressBar.setVisibility(View.GONE);
            ServerResponse server = response.body();
            Log.i(TAG, "response callback");
            if (server != null) {
                for (Result result : server.getResults()) {
                    Log.i("server", result.getHostName());
                    Log.i("server", result.getIP());
                    Log.i("server", result.getScore());
                    Log.i("server", result.getLatency());
                    Log.i("server", result.getCountryLong());
                    Log.i("server", result.getCountryShort());

                    data.add(result.getCountryLong());
                    progressBar.setVisibility(View.GONE);
                    flagLink.add("http://v4v.info/countryflag/" + result.getCountryShort().toLowerCase() + ".png");
                }

                //Log.i(TAG, "onResponse: " + flagLink);

                recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
                MyAdapter adapter = new MyAdapter(getActivity(), data, flagLink);
                recyclerView.setAdapter(adapter);
            }
        }

        @Override
        public void onFailure(@NonNull Call<ServerResponse> call, @NonNull Throwable t) {
            Log.i(TAG, "onFailure: " + t.getMessage());
        }
    });
</code>```

This is working for another version of android like android API 24 and others but not in Android 9(Pie) and Android Oreo (8.1). I want to run this in the Android 9(Pie) and Oreo (8.1).

答:
Add this line in your manifest file.

<application...>
   <uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application>

it's helped for me for android API 24+. try this.

Body:
I'm Parsing some data from the server by Retrofit2. In other versions of Android and emulator, it is working fine. But the problem is it is not working in Android 9 (Pie) and Android Oreo (8.1). For this reason, the app is going to crash every time I installed. Another problem is, it's not showing any Error in the Logcat. So what can be the solution?

By reading some blogs and Stack Overflow, I have tried by adding android:usesCleartextTraffic="true" in the AndroidManifest. I have also added the below file in the AndroidManifest.

android:networkSecurityConfig="@xml/network_security_config"

where network_security_config file is

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">116.203.27.235/</domain>
    </domain-config>
</network-security-config>

Here is the request code I made:

ApiInterface api = retrofit.create(ApiInterface.class);
Call<ServerResponse> call = api.getServerResult(new String(encodeValue));

call.enqueue(new Callback<ServerResponse>() {
        @Override
        public void onResponse(@NonNull Call<ServerResponse> call, @NonNull Response<ServerResponse> response) {
            Log.i(TAG, "onResponse: " + response.message());
            progressBar.setVisibility(View.GONE);
            ServerResponse server = response.body();
            Log.i(TAG, "response callback");
            if (server != null) {
                for (Result result : server.getResults()) {
                    Log.i("server", result.getHostName());
                    Log.i("server", result.getIP());
                    Log.i("server", result.getScore());
                    Log.i("server", result.getLatency());
                    Log.i("server", result.getCountryLong());
                    Log.i("server", result.getCountryShort());

                    data.add(result.getCountryLong());
                    progressBar.setVisibility(View.GONE);
                    flagLink.add("http://v4v.info/countryflag/" + result.getCountryShort().toLowerCase() + ".png");
                }

                //Log.i(TAG, "onResponse: " + flagLink);

                recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
                MyAdapter adapter = new MyAdapter(getActivity(), data, flagLink);
                recyclerView.setAdapter(adapter);
            }
        }

        @Override
        public void onFailure(@NonNull Call<ServerResponse> call, @NonNull Throwable t) {
            Log.i(TAG, "onFailure: " + t.getMessage());
        }
    });

This is working for another version of android like android API 24 and others but not in Android 9(Pie) and Android Oreo (8.1). I want to run this in the Android 9(Pie) and Oreo (8.1).