问:
Learning WPF without success
Hello developers and designers,

I am very willing to learn WPF in which i use C# as the logic code.
Or i 'try' to anyway.

I have written a 2-page long code-behind in Forms-style though, so i know some syntaxes.
But that was a really cumbersome way of doing it.

The problem is that i am still lingering around the area of understanding at least the basic concept of object oriented programming. But 9 out of 10 times i am not getting the example-codes entirely because of that '1 little thing of which i don't even know what it's called'.
How do you even know if there is a command for the function you want to express and more importantly.... how it's called and where it located in what namespace?

Even the best video-examples aren't doing it for me, because when any code is typed, they never explain how the code exactly works. And most of the times it just doesn't even add up to what i know of logic code (of course i'm wrong).

In the early days i learned the Commodore64's Basic no problem.
Learning and writing Actionscript (Flash), within 2 months creating a 2D-shoot'em up
Learning and writing CMD, within 3 months writing 5000+ lines of code for all sorts of functions.

Why in Merlin's beard is WPF so hard?
Watching the "simplest" tutorial-video's are becoming more and more de-motivational.

Anyone recognizes this?

Thanks for reading,
Danny

答:
Regarding WPF the articles I've found to be most useful are the overviews on MSDN, they might take quite some time to work through but they are concise and in-depth, see this page for a master-overview.

Why WPF is hard is a good question, one primary cause might be that it is simply huge, at least i perceive it that way. Aside from having all the code you also now have XAML markup which is a world of its own.

Someone from Microsoft who did a presentation on F# in 2008 said that if you know three of the keywords, let, fun & |>, you know the whole language, which is not even that much of an overstatement. WPF on the other hand is not a language, it is a sub-framework. If F# can be likened to 3 nanotechnology building blocks then WPF is a 50 meter workbench stacked with tools (the controls) and a dozen heavy duty machines (WPF mechanisms like dependency properties, data binding, commanding, data templating, etc.), and all of those come with a manual. So if you are facing a problem you pretty much need to know what all the tools and machines do so you know which to use, and then of course you also need to know how to use them, apart from their basic functionality each may even have its own kinks and peculiarities which are important to keep in mind.

So learning WPF requires a lot of raw knowledge of the framework but also experience so you know what is the best approach in a given situation and to get a feeling for what can be done and what cannot.

ContentLicense: CC BY-SA 3.0

Title: Learning WPF without success


来源: stackexchange

问:
Insert data into table and get ID from increased primary key
In my ASP.NET application I have a need to do something like this: First, get data from a user, second insert this data into SQL Server database table, then get the ID value from that table (which is autoincremented) and then use it in another insert into another table.

Now, I already found out that in order to do this, I need to use T-SQL OUTPUT clause. However, when I try to do this I get this error:

I tried to follow the advice from those posts:
Get output parameter value in ADO.NET and Use SQL Server Stored procedure output in asp.net c#
but I couldn't make it work.

I'm not using stored procedure, but the single SQL statement instead. Here it is:

```<code>INSERT INTO BS_product_sets (User_id, Set_name, Set_id, Products_count)
OUTPUT inserted.ID INTO @NEWID
VALUES (@UID, @SNAME, @SPREFIX, @PCOUNT)
</code>```

I also tried this:

```<code>DECLARE @NEWID int;

INSERT INTO BS_product_sets (User_id, Set_name, Set_id, Products_count)
OUTPUT inserted.ID INTO @NEWID
VALUES (@UID, @SNAME, @SPREFIX, @PCOUNT)
</code>```

But then it gets even weirder because the error I get is:

Does anyone of you know how to resolve it? Here is the rest of my code in C#:

```<code>public void InsertProductAutoBinds(int user_id, int parameters_count, List<int> cat_ids, List<string> names, List<string> values, string set_name, string set_id)
{
    SqlConnection connection = new SqlConnection(DatabaseConstants.ConnectionString);

    // Adding set to database
    SqlCommand command = new SqlCommand(DatabaseConstants.InsertSet, connection);
    command.Parameters.AddWithValue("@UID", user_id);
    command.Parameters.AddWithValue("@SNAME", set_name);
    command.Parameters.AddWithValue("@SPREFIX", set_id);
    command.Parameters.AddWithValue("@PCOUNT", 0);
    command.Parameters.Add("@NEWID", SqlDbType.Int).Direction = ParameterDirection.Output;

    connection.Open();
    command.ExecuteNonQuery();

    int new_inserted_id = Convert.ToInt32(command.Parameters["@NEWID"].Value);

    connection.Close();

    // Adding binds
    command = new SqlCommand(DatabaseConstants.InsertAutoBinds1, connection);
    command.Parameters.AddWithValue("@UID", user_id);
    command.Parameters.AddWithValue("@SID", new_inserted_id);
    command.Parameters.AddWithValue("@P1ID", cat_ids[0]);
    command.Parameters.AddWithValue("@VN1", names[0]);
    command.Parameters.AddWithValue("@VS1", values[0]);

    if (parameters_count > 1)
    {
        command.CommandText = DatabaseConstants.InsertAutoBinds2;
        command.Parameters.AddWithValue("@P2ID", cat_ids[1]);
        command.Parameters.AddWithValue("@VN2", names[1]);
        command.Parameters.AddWithValue("@VS2", values[1]);
    }

    if (parameters_count > 2)
    {
        command.CommandText = DatabaseConstants.InsertAutoBinds3;
        command.Parameters.AddWithValue("@P3ID", cat_ids[2]);
        command.Parameters.AddWithValue("@VN3", names[2]);
        command.Parameters.AddWithValue("@VS3", values[2]);
    }

    connection.Open();
    command.ExecuteNonQuery();
    connection.Close();
}
</code>```

答:
If you look at the official MS documentation for INSERT INTO, you'd see:

OUTPUT  INTO { @table_variable | output_table }

That means: the OUTPUT ... INTO .... clause only works with a table or table variable as its target - you cannot do an OUTPUT .... INTO @variable - that's just plain not supported.

So you need to

either do an OUTPUT ... INTO @tableVar and then select the first value from that table variable and return it

just use OUTPUT inserted.ID (without any INTO ....) and just grab the value being returned from the SQL command in your C# code - in this case, since data is being returned, you need to use .ExecuteScalar() instead of .ExecuteNonQuery() in your C# code

ContentLicense: CC BY-SA 4.0

Body:
In my ASP.NET application I have a need to do something like this: First, get data from a user, second insert this data into SQL Server database table, then get the ID value from that table (which is autoincremented) and then use it in another insert into another table.

Now, I already found out that in order to do this, I need to use T-SQL OUTPUT clause. However, when I try to do this I get this error:

I tried to follow the advice from those posts:
Get output parameter value in ADO.NET and Use SQL Server Stored procedure output in asp.net c#
but I couldn't make it work.

I'm not using stored procedure, but the single SQL statement instead. Here it is:

INSERT INTO BS_product_sets (User_id, Set_name, Set_id, Products_count)
OUTPUT inserted.ID INTO @NEWID
VALUES (@UID, @SNAME, @SPREFIX, @PCOUNT)

I also tried this:

DECLARE @NEWID int;

INSERT INTO BS_product_sets (User_id, Set_name, Set_id, Products_count)
OUTPUT inserted.ID INTO @NEWID
VALUES (@UID, @SNAME, @SPREFIX, @PCOUNT)

But then it gets even weirder because the error I get is:

Does anyone of you know how to resolve it? Here is the rest of my code in C#:

public void InsertProductAutoBinds(int user_id, int parameters_count, List<int> cat_ids, List<string> names, List<string> values, string set_name, string set_id)
{
    SqlConnection connection = new SqlConnection(DatabaseConstants.ConnectionString);

    // Adding set to database
    SqlCommand command = new SqlCommand(DatabaseConstants.InsertSet, connection);
    command.Parameters.AddWithValue("@UID", user_id);
    command.Parameters.AddWithValue("@SNAME", set_name);
    command.Parameters.AddWithValue("@SPREFIX", set_id);
    command.Parameters.AddWithValue("@PCOUNT", 0);
    command.Parameters.Add("@NEWID", SqlDbType.Int).Direction = ParameterDirection.Output;

    connection.Open();
    command.ExecuteNonQuery();

    int new_inserted_id = Convert.ToInt32(command.Parameters["@NEWID"].Value);

    connection.Close();

    // Adding binds
    command = new SqlCommand(DatabaseConstants.InsertAutoBinds1, connection);
    command.Parameters.AddWithValue("@UID", user_id);
    command.Parameters.AddWithValue("@SID", new_inserted_id);
    command.Parameters.AddWithValue("@P1ID", cat_ids[0]);
    command.Parameters.AddWithValue("@VN1", names[0]);
    command.Parameters.AddWithValue("@VS1", values[0]);

    if (parameters_count > 1)
    {
        command.CommandText = DatabaseConstants.InsertAutoBinds2;
        command.Parameters.AddWithValue("@P2ID", cat_ids[1]);
        command.Parameters.AddWithValue("@VN2", names[1]);
        command.Parameters.AddWithValue("@VS2", values[1]);
    }

    if (parameters_count > 2)
    {
        command.CommandText = DatabaseConstants.InsertAutoBinds3;
        command.Parameters.AddWithValue("@P3ID", cat_ids[2]);
        command.Parameters.AddWithValue("@VN3", names[2]);
        command.Parameters.AddWithValue("@VS3", values[2]);
    }

    connection.Open();
    command.ExecuteNonQuery();
    connection.Close();
}


问:
How can I type a prop of an object depending on another prop's type?
Consider the next example:

enum ActionTypes {
    A = 'A',
    B = 'B'
}

type ActionProps = {
    [ActionTypes.A]: {
        a: string
    }
    [ActionTypes.B]: {
        b: string
    }
}

type Action = {
    [type in keyof ActionProps]: {
        type: type
    } & ActionProps[type]
}

//produces the expected result, but not ideal for the case

const state1: Action[ActionTypes] = {
    type: ActionTypes.A,
    a: 'string',
};

(() => {
    if (state1.type === ActionTypes.A) {
        state1.a = 'anotherstring';
        //doesn't error, because the compiler knows
        //the possible properties by state.type
    }
})();

//doesn't produce the expected result, but it would be ideal for the case

type State = {
    type: ActionTypes
    actionProps: ActionProps[State['type']]
}

const state2: State = {
    type: ActionTypes.A,
    actionProps: {
        a: 'string',
        b: 'string',
    }
};

(() => {
    if (state2.type === ActionTypes.A) {
        state2.actionProps.a = 'anotherstring';
        //errors - Property 'a' does not exist on type '{ b: string; }'
    }
})();
```

Playground

The expected result would be that if the compiler knows that state.type === ActionTypes.A, it knows that the type of state.actionProps is ActionProps[ActionTypes.A].

Are there any possible workaround for that?

答:
You might be looking for a generic:

```<code>enum ActionTypes {
    A = 'A',
    B = 'B'
}

type ActionProps = {
    [ActionTypes.A]: {
        a: string
    }
    [ActionTypes.B]: {
        b: string
    }
}

type State<Type extends keyof ActionProps> = {
    type: Type
    actionProps: ActionProps[Type] & ActionProps[keyof ActionProps]
}

const state: State<ActionTypes.A> = {
    type: ActionTypes.A,
    actionProps: {
        a: 'string',
        b: 'string',
    }
};

(() => {
    if (state.type === ActionTypes.A) {
        state.actionProps.a = 'anotherstring';
        //errors - Property 'a' does not exist on type '{ b: string; }'
    }
})();
</code>```

However, it seems TypeScript is not able to infer the type parameter based on the value of the .type property, that feature appears to be reserved for discriminated unions.

Body:
Consider the next example:

enum ActionTypes {
    A = 'A',
    B = 'B'
}

type ActionProps = {
    [ActionTypes.A]: {
        a: string
    }
    [ActionTypes.B]: {
        b: string
    }
}

type Action = {
    [type in keyof ActionProps]: {
        type: type
    } & ActionProps[type]
}

//produces the expected result, but not ideal for the case

const state1: Action[ActionTypes] = {
    type: ActionTypes.A,
    a: 'string',
};

(() => {
    if (state1.type === ActionTypes.A) {
        state1.a = 'anotherstring';
        //doesn't error, because the compiler knows
        //the possible properties by state.type
    }
})();

//doesn't produce the expected result, but it would be ideal for the case

type State = {
    type: ActionTypes
    actionProps: ActionProps[State['type']]
}

const state2: State = {
    type: ActionTypes.A,
    actionProps: {
        a: 'string',
        b: 'string',
    }
};

(() => {
    if (state2.type === ActionTypes.A) {
        state2.actionProps.a = 'anotherstring';
        //errors - Property 'a' does not exist on type '{ b: string; }'
    }
})();

<a href="http://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=56&pc=6#code/KYOwrgtgBAggxgFwJYHsQBUCeAHYBnKAbwFgAoKC2KAXigHIY6AaMyqAIRvvbrIF8yZBDmCxEqEAAUATimwFaJcpQDa8ZGiy48AOhgBdAFxFWbSgENjeBNKQgA5qYoDlFNeM0jd7IyddmAIysbO0d-FxchETENEC4lNhVhXCg7KABrYEwUADMYiRk5PF8Eswpk4GMKpyg%20KAAyfLRC%20SSRfX5BUgB6buxZABMwOHwoBAALUWAAD1xEYAGoaXwwABsEJigAsAQoEBRdpAHgc1WoHJRpMcmoOHM8YC64NGsoa3MEYABGY3UJd1iWnw%20niNQqvw8GC8ehY-ks9GstgczH4AG4ugAKDEAShoAD4-GwkHkMe9Pl8dBUaNRaH9PNo9LjSmUyd8dOYuHRzPsJsBpIjQnR0f42L0Bih8CA6Ls%20bJpJsAsA7mAHtdRM8INgkKs%20Rl9gB3PA1UXdXlQbAoPB4JABHXm2S4aTIUYBTBvBAfYCUkQ1CLYnHCshiiV4KW7fooIYjNVQGZzT6LZZ4NYbLY7VK7fUoNaLRWpY6nc6XGN3B5dKkAZQ9n1B-nBTSh2hq5khLTwENibZUVc9KmlIjo%20g6pEipGeIFerIATMYezXFGCRB2JEDdDBYWwW52He3CWUoPC6ALkRv90EESET760Zicfi9xRiVBSdXgFPvSkabTIavGQ%20zNO7Ktju7KctyByTPyl72EKxqUL0sqXAQAC0UAtHywj0OYdBQOKow8rG0xIK8aBjNEdCEFswRIvYqK1Lw4T8P62KokAA" rel="nofollow noreferrer">Playground

The expected result would be that if the compiler knows that state.type === ActionTypes.A, it knows that the type of state.actionProps is ActionProps[ActionTypes.A].

Are there any possible workaround for that?

Body:
You might be looking for a generic:

enum ActionTypes {
    A = 'A',
    B = 'B'
}

type ActionProps = {
    [ActionTypes.A]: {
        a: string
    }
    [ActionTypes.B]: {
        b: string
    }
}

type State<Type extends keyof ActionProps> = {
    type: Type
    actionProps: ActionProps[Type] & ActionProps[keyof ActionProps]
}

const state: State<ActionTypes.A> = {
    type: ActionTypes.A,
    actionProps: {
        a: 'string',
        b: 'string',
    }
};

(() => {
    if (state.type === ActionTypes.A) {
        state.actionProps.a = 'anotherstring';
        //errors - Property 'a' does not exist on type '{ b: string; }'
    }
})();

However, it seems TypeScript is not able to infer the type parameter based on the value of the .type property, that feature appears to be reserved for discriminated unions.


问:
Error when saving a document using a web application in c#
I have a web application in c#,that creates and save a document in local machine folder.
The works fine when running from my machine - however as soon as I deploy the app to my web server I get this error.

This is not a valid file name. Try one or more of the following: *
  Check the path to make sure it was typed correctly. * Select a file
  from the list of files and folders.

Below is my source code

```<code>            //Create an instance for word app
            Microsoft.Office.Interop.Word.Application winword = new Microsoft.Office.Interop.Word.Application();

            //Set animation status for word application
            winword.ShowAnimation = false;

            //Set status for word application is to be visible or not.
            winword.Visible = false;

            //Create a missing variable for missing value
            object missing = System.Reflection.Missing.Value;

            //Create a new document
            Microsoft.Office.Interop.Word.Document document = winword.Documents.Add(ref missing, ref missing, ref missing, ref missing);

            //Add header into the document
            //foreach (Microsoft.Office.Interop.Word.Section section in document.Sections)
            //{
            //    //Get the header range and add the header details.
            //    Microsoft.Office.Interop.Word.Range headerRange = section.Headers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
            //    headerRange.Fields.Add(headerRange, Microsoft.Office.Interop.Word.WdFieldType.wdFieldPage);
            //    headerRange.ParagraphFormat.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphCenter;
            //    headerRange.Font.ColorIndex = Microsoft.Office.Interop.Word.WdColorIndex.wdBlue;
            //    headerRange.Font.Size = 10;
            //    headerRange.Text = "Header text goes here";
            //}

            //Add the footers into the document
            //foreach (Microsoft.Office.Interop.Word.Section wordSection in document.Sections)
            //{
            //    //Get the footer range and add the footer details.
            //    Microsoft.Office.Interop.Word.Range footerRange = wordSection.Footers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
            //    footerRange.Font.ColorIndex = Microsoft.Office.Interop.Word.WdColorIndex.wdDarkRed;
            //    footerRange.Font.Size = 10;
            //    footerRange.ParagraphFormat.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphCenter;
            //    footerRange.Text = "Footer text goes here";
            //}

            //adding text to document
            document.Content.SetRange(0, 0);
            document.Content.Text = "This is test document " + Environment.NewLine;

            //Add paragraph with Heading 1 style
            Microsoft.Office.Interop.Word.Paragraph para1 = document.Content.Paragraphs.Add(ref missing);
            object styleHeading1 = "Heading 1";
            para1.Range.set_Style(ref styleHeading1);
            para1.Range.Text = "Para 1 text";
            para1.Range.InsertParagraphAfter();

            //Add paragraph with Heading 2 style
            Microsoft.Office.Interop.Word.Paragraph para2 = document.Content.Paragraphs.Add(ref missing);
            object styleHeading2 = "Heading 2";
            para2.Range.set_Style(ref styleHeading2);
            para2.Range.Text = "Para 2 text";
            para2.Range.InsertParagraphAfter();

            //Create a 5X5 table and insert some dummy record
            Microsoft.Office.Interop.Word.Table firstTable = document.Tables.Add(para1.Range, 5, 5, ref missing, ref missing);

            firstTable.Borders.Enable = 1;
            foreach (Row row in firstTable.Rows)
            {
                foreach (Cell cell in row.Cells)
                {
                    //Header row
                    if (cell.RowIndex == 1)
                    {
                        cell.Range.Text = "Column " + cell.ColumnIndex.ToString();
                        cell.Range.Font.Bold = 1;
                        //other format properties goes here
                        cell.Range.Font.Name = "verdana";
                        cell.Range.Font.Size = 10;
                        //cell.Range.Font.ColorIndex = WdColorIndex.wdGray25;
                        cell.Shading.BackgroundPatternColor = WdColor.wdColorGray25;
                        //Center alignment for the Header cells
                        cell.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
                        cell.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;

                    }
                    //Data row
                    else
                    {
                        cell.Range.Text = (cell.RowIndex - 2 + cell.ColumnIndex).ToString();
                    }
                }
            }

            //Save the document
            object filename = @"c:\Data\TestSignature.doc";

            document.SaveAs(ref filename);
            document.Close(ref missing, ref missing, ref missing);
            document = null;
            winword.Quit(ref missing, ref missing, ref missing);
            winword = null;
            Label7.Text = "Document created successfully !";
</code>```

答:
You can not write anywhere on server - for example you can not use this directory @"c:\Data\TestSignature.doc"; Maybe if you add permissions, but better not.

Use this directory inside your asp.net folder to write data that you do not want to access public.

```<code>/App_Data/
</code>```

Or make some other directory in your web site folder and saved them there.

You can use the HttpRuntime.AppDomainAppPath to get the path of your site, and add the extra directory.

In the folder you going to write you must give write permissions of your pool identity :
How to set correct file permissions for ASP.NET on IIS

Body:
I have a web application in c#,that creates and save a document in local machine folder.
The works fine when running from my machine - however as soon as I deploy the app to my web server I get this error.

This is not a valid file name. Try one or more of the following: *
  Check the path to make sure it was typed correctly. * Select a file
  from the list of files and folders.

Below is my source code

            //Create an instance for word app
            Microsoft.Office.Interop.Word.Application winword = new Microsoft.Office.Interop.Word.Application();

            //Set animation status for word application
            winword.ShowAnimation = false;

            //Set status for word application is to be visible or not.
            winword.Visible = false;

            //Create a missing variable for missing value
            object missing = System.Reflection.Missing.Value;

            //Create a new document
            Microsoft.Office.Interop.Word.Document document = winword.Documents.Add(ref missing, ref missing, ref missing, ref missing);

            //Add header into the document
            //foreach (Microsoft.Office.Interop.Word.Section section in document.Sections)
            //{
            //    //Get the header range and add the header details.
            //    Microsoft.Office.Interop.Word.Range headerRange = section.Headers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
            //    headerRange.Fields.Add(headerRange, Microsoft.Office.Interop.Word.WdFieldType.wdFieldPage);
            //    headerRange.ParagraphFormat.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphCenter;
            //    headerRange.Font.ColorIndex = Microsoft.Office.Interop.Word.WdColorIndex.wdBlue;
            //    headerRange.Font.Size = 10;
            //    headerRange.Text = "Header text goes here";
            //}

            //Add the footers into the document
            //foreach (Microsoft.Office.Interop.Word.Section wordSection in document.Sections)
            //{
            //    //Get the footer range and add the footer details.
            //    Microsoft.Office.Interop.Word.Range footerRange = wordSection.Footers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
            //    footerRange.Font.ColorIndex = Microsoft.Office.Interop.Word.WdColorIndex.wdDarkRed;
            //    footerRange.Font.Size = 10;
            //    footerRange.ParagraphFormat.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphCenter;
            //    footerRange.Text = "Footer text goes here";
            //}

            //adding text to document
            document.Content.SetRange(0, 0);
            document.Content.Text = "This is test document " + Environment.NewLine;

            //Add paragraph with Heading 1 style
            Microsoft.Office.Interop.Word.Paragraph para1 = document.Content.Paragraphs.Add(ref missing);
            object styleHeading1 = "Heading 1";
            para1.Range.set_Style(ref styleHeading1);
            para1.Range.Text = "Para 1 text";
            para1.Range.InsertParagraphAfter();

            //Add paragraph with Heading 2 style
            Microsoft.Office.Interop.Word.Paragraph para2 = document.Content.Paragraphs.Add(ref missing);
            object styleHeading2 = "Heading 2";
            para2.Range.set_Style(ref styleHeading2);
            para2.Range.Text = "Para 2 text";
            para2.Range.InsertParagraphAfter();

            //Create a 5X5 table and insert some dummy record
            Microsoft.Office.Interop.Word.Table firstTable = document.Tables.Add(para1.Range, 5, 5, ref missing, ref missing);

            firstTable.Borders.Enable = 1;
            foreach (Row row in firstTable.Rows)
            {
                foreach (Cell cell in row.Cells)
                {
                    //Header row
                    if (cell.RowIndex == 1)
                    {
                        cell.Range.Text = "Column " + cell.ColumnIndex.ToString();
                        cell.Range.Font.Bold = 1;
                        //other format properties goes here
                        cell.Range.Font.Name = "verdana";
                        cell.Range.Font.Size = 10;
                        //cell.Range.Font.ColorIndex = WdColorIndex.wdGray25;
                        cell.Shading.BackgroundPatternColor = WdColor.wdColorGray25;
                        //Center alignment for the Header cells
                        cell.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
                        cell.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;

                    }
                    //Data row
                    else
                    {
                        cell.Range.Text = (cell.RowIndex - 2 + cell.ColumnIndex).ToString();
                    }
                }
            }

            //Save the document
            object filename = @"c:\Data\TestSignature.doc";

            document.SaveAs(ref filename);
            document.Close(ref missing, ref missing, ref missing);
            document = null;
            winword.Quit(ref missing, ref missing, ref missing);
            winword = null;
            Label7.Text = "Document created successfully !";

Body:
You can not write anywhere on server - for example you can not use this directory @"c:\Data\TestSignature.doc"; Maybe if you add permissions, but better not.

Use this directory inside your asp.net folder to write data that you do not want to access public.

/App_Data/

Or make some other directory in your web site folder and saved them there.

You can use the HttpRuntime.AppDomainAppPath to get the path of your site, and add the extra directory.

In the folder you going to write you must give write permissions of your pool identity :
How to set correct file permissions for ASP.NET on IIS


问:
What is the valid form of alias names?
I'm trying to implement a basic behavior for alias command in bash, I just want to know the valid form of the names.</p>

答:
I took a peek at the Bash source, and @chepner's comment is correct. Any characters that aren't interpreted by the shell already are valid. So things like $, /, and = are not allowed.

From general.c, https://ftp.gnu.org/gnu/bash/bash-5.0.tar.gz

/* Return 1 if STRING comprises a valid alias name.  The shell accepts
   essentially all characters except those which must be quoted to the
   parser (which disqualifies them from alias expansion anyway) and `/'. */
int
legal_alias_name (string, flags)
     const char *string;
     int flags;
{
  register const char *s;

  for (s = string; *s; s++)
    if (shellbreak (*s) || shellxquote (*s) || shellexp (*s) || (*s == '/'))
      return 0;
  return 1;
}
```

Title: What is the valid form of alias names?


问:
Create Group from Sequences
How can I create a "group" vector that identifies sequences of same values in another vector.

From this

```<code>x <- c(0,1,0,0,1,0,1)
</code>```

I want to create this

```<code>outcome <- c(1,2,3,3,4,5,6)

[1] 0 1 0 0 1 0 1
[1] 1 2 3 3 4 5 6
</code>```

So, whenever there is a new sequence of the same values there is a new group number (or can be something other than a number as well).

I would actually know ways to get there, but they are all hideous. The best I can come up with is

```<code>comparison <- x != lag(x)
cumsum(replace_na(comparison, TRUE))
</code>```

but like I said - hideous. There must be a better way and I hope someone knows it.

答:
a tidyverse version that does a condition, replaces the NA and sums cumulatively:

```<code>library(tidyverse)

if_else(outcome == lag(outcome), 0, 1) %>%
  replace_na(1) %>%
  cumsum()

[1] 1 2 3 3 4 5 6
</code>```

Title: Create Group from Sequences

Body:
How can I create a "group" vector that identifies sequences of same values in another vector.

From this

x <- c(0,1,0,0,1,0,1)

I want to create this

outcome <- c(1,2,3,3,4,5,6)

[1] 0 1 0 0 1 0 1
[1] 1 2 3 3 4 5 6

So, whenever there is a new sequence of the same values there is a new group number (or can be something other than a number as well).

I would actually know ways to get there, but they are all hideous. The best I can come up with is

comparison <- x != lag(x)
cumsum(replace_na(comparison, TRUE))

but like I said - hideous. There must be a better way and I hope someone knows it.

Body:
a tidyverse version that does a condition, replaces the NA and sums cumulatively:

library(tidyverse)

if_else(outcome == lag(outcome), 0, 1) %>%
  replace_na(1) %>%
  cumsum()

[1] 1 2 3 3 4 5 6


问:
How do I make an image load synchronously?
I want to create an object that has an image property, but I want the contstructor to finish running only once the image is loaded. Or to describe this with code:

```<code>GraphicObject = Class.extend({

    //This is the constructor
    init: function(){
          this.graphic = new Image();
          this.graphic.src = 'path/to/file.png';

          while(true)
          {
              this.graphic.onload = function(){break;};
              //I know this won't work since the 'break' is on a different context
              //but you got what I try to do.
          }
     }

})
</code>```

For those who are unfamiliar with the Class notation I'm using in my script, it's based on this

Any ideas?

答:
There is a non-evil way to load images in Javascript synchronously.

```<code>loadImage = async img => {
    return new Promise((resolve, reject) => {
        img.onload = async () => {
            console.log("Image Loaded");
            resolve(true);
        };
    });
};
</code>```

Call it with await anywhere. like this

```<code>for(let i=0;i<photos.length;i++){
    await loadImage(photos[i]);
}
</code>```

It will load all images one by one.

Note: Calling function must be async to use await

Body:
I want to create an object that has an image property, but I want the contstructor to finish running only once the image is loaded. Or to describe this with code:

GraphicObject = Class.extend({

    //This is the constructor
    init: function(){
          this.graphic = new Image();
          this.graphic.src = 'path/to/file.png';

          while(true)
          {
              this.graphic.onload = function(){break;};
              //I know this won't work since the 'break' is on a different context
              //but you got what I try to do.
          }
     }

})

For those who are unfamiliar with the Class notation I'm using in my script, it's based on this

Any ideas?

Body:
There is a non-evil way to load images in Javascript synchronously.

loadImage = async img => {
    return new Promise((resolve, reject) => {
        img.onload = async () => {
            console.log("Image Loaded");
            resolve(true);
        };
    });
};

Call it with await anywhere. like this

for(let i=0;i<photos.length;i++){
    await loadImage(photos[i]);
}

It will load all images one by one.

Note: Calling function must be async to use await


问:
Map object support in Google Apps Script
Does Google Apps Script supports the Map object?

When I try to use it I get:

```<code>ReferenceError: "Map" is not defined. (line 21, file "Code")
</code>```

答:
Now is possible by changing your script to use the new runtime that runs on V8.
Enable it in the menu "Run/Enable new Apps Script runtime powered by Chrome V8"

```<code>function testMap(){
  var m = new Map();
  m.set("a", "value")
  Logger.log(m.get("a"));
}
</code>```

Output:

```<code>[20-02-16 12:25:42:404 CST] value
</code>```

Body:
Does Google Apps Script supports the Map object?

When I try to use it I get:

ReferenceError: "Map" is not defined. (line 21, file "Code")

Body:
Now is possible by changing your script to use the new runtime that runs on V8.
Enable it in the menu "Run/Enable new Apps Script runtime powered by Chrome V8"

function testMap(){
  var m = new Map();
  m.set("a", "value")
  Logger.log(m.get("a"));
}

Output:

[20-02-16 12:25:42:404 CST] value


问:
Form refreshes constantly with $.submit()
Something is eluding me here. Every time I press the submit button, the form just refreshes the page and I never get the "Form Submitted" message. I don't want the form to refresh the page.</p>

```<code><!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Test</title>

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
        <script type="text/javascript">

            (function($){

                $("#my-form").submit(function(e){
                    e.preventDefault();
                    alert("Form Submitted");
                });

            })(jQuery);

        </script>
    </head>
    <body>

        <form id="my-form" method="post" action="">

            <input type="text" placeholder="Input something..." />
            <input type="submit" value="Submit" />

        </form>

    </body>
</html>
</code>```

答:
You need to wrap your code with a DOM ready event.

```<code>$(function() {
   ...
});
</code>```

Your code as now tries to bind the event when the element isn't ready in the DOM, therefore the event is never attached.

Body:
Something is eluding me here. Every time I press the submit button, the form just refreshes the page and I never get the "Form Submitted" message. I don't want the form to refresh the page.

<!DOCTYPE html>

        <meta charset="UTF-8" />
        <title>Test</title>

        <form id="my-form" method="post" action="">

            <input type="text" placeholder="Input something..." />
            <input type="submit" value="Submit" />

        </form>

Body:
You need to wrap your code with a DOM ready event.

$(function() {
   ...
});

Your code as now tries to bind the event when the element isn't ready in the DOM, therefore the event is never attached.


问:
I have 2 boxes and a picture. The user can drag the picture between the 2 boxes. How do I tell which box the picture is dragged from?
I have 2 boxes and a picture. The user can drag the picture between the 2 boxes. How do I tell which box the picture is dragged from? I tried looking at the parent element of the picture but that didn't work because the HTML doesn't change, I guess.

<!DOCTYPE html>

```

Or, view a TryIt here: https://www.w3schools.com/code/tryit.asp?filename=GBYRXSX3L0PP

Thanks in advance!

答:
In your code you are running:

```<code>var nodeCopy = document.getElementById(data).cloneNode(true);
</code>```

I believe that this is copying the root element (the reference of the original) and duplicating its original details which would mean that all elements have originated from the blue box -

Instead of using clone node maybe try

1)

creating an element div and appending it to the location provided by the user input by the drag and drop

2)

writing strick html for the element and using incertAdjacenthtml
https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

Have a look at this post on the subject of creating original cloned elements from a source element

How do I correctly clone a JavaScript object?

I hope this helps you debug!

Wally

Body:
I have 2 boxes and a picture. The user can drag the picture between the 2 boxes. How do I tell which box the picture is dragged from? I tried looking at the parent element of the picture but that didn't work because the HTML doesn't change, I guess.

<!DOCTYPE html>

Or, view a TryIt here: https://www.w3schools.com/code/tryit.asp?filename=GBYRXSX3L0PP

Thanks in advance!

Body:
In your code you are running:

var nodeCopy = document.getElementById(data).cloneNode(true);

I believe that this is copying the root element (the reference of the original) and duplicating its original details which would mean that all elements have originated from the blue box -

Instead of using clone node maybe try

1)

creating an element div and appending it to the location provided by the user input by the drag and drop

2)

writing strick html for the element and using incertAdjacenthtml
https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

Have a look at this post on the subject of creating original cloned elements from a source element

How do I correctly clone a JavaScript object?

I hope this helps you debug!

Wally


问:
what is the correct behaviour of this csrrw
I am working with RISCV Privileged 1.7 Instruction set, Page 8 describes csrrw.

When the processor is executing :

```<code>csrrw   a0,cycle,a0
</code>```

Should it update the "a0" register with CSR "cycle" value and also raise an exception as it is written in user mode?

or

Should it raise the exception and not update the CSR "cycle" register?

答:
The RISC-V Privileged Architecture document specifies that cycle is a read-only CSR and thus any write to it should yield an illegal instruction exception.

Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions.

(emphasis mine, Section 2.1 CSR Address Mapping Conventions, page 5, The RISC-V Instruction Set Manual. Volume II: Privileged Architecture. 1.12-draft)

The specification leaves it unspecified what happens to the destination register if an illegal instruction exception is raised because of a write to an read-only CSR.

That means whether an implementation writes the destination register or not it is conforming to the specification as long as it raises an illegal instruction exception.

Body:
I am working with RISCV Privileged 1.7 Instruction set, Page 8 describes csrrw.

When the processor is executing :

csrrw   a0,cycle,a0

Should it update the "a0" register with CSR "cycle" value and also raise an exception as it is written in user mode?

or

Should it raise the exception and not update the CSR "cycle" register?


问:
Why is a reference needed in operator overloading?
In what situations would a reference be needed when overloading, as the code still works without it? I am aware it has something to with chaining, but I do not understand exactly why the reference is needed.

Example:

```<code>Object& operator++();
</code>```

答:
Without the 'reference', the operator function will return by value - and that will be a copy of the original object - which is not what is intended.

For example, try the following code with and without the use of the 'reference', and you will see different results from the final one.show() call:

#include <iostream>

class myInt {
private:
    int value;
public:
    myInt() : value{ 0 } { }
    myInt(int x) : value{ x } { }
//    myInt operator ++() { ++value; return *this; }
    myInt& operator ++() { ++value; return *this; }
    void show() {
        std::cout << value << std::endl;
    }
};

int main(int argc, char* argv[])
{
    myInt one(1);
    one.show();
    myInt two = ++(++one);
    two.show();
    one.show(); // Difference shows here!
    return 0;
}
```

This is because, without the reference, the ++ outside the parentheses operates on a locally-created copy of the one object.

Body:
In what situations would a reference be needed when overloading, as the code still works without it? I am aware it has something to with chaining, but I do not understand exactly why the reference is needed.

Example:

Object& operator++();

Body:
Without the 'reference', the operator function will return by value - and that will be a copy of the original object - which is not what is intended.

For example, try the following code with and without the use of the 'reference', and you will see different results from the final one.show() call:

#include <iostream>

class myInt {
private:
    int value;
public:
    myInt() : value{ 0 } { }
    myInt(int x) : value{ x } { }
//    myInt operator ++() { ++value; return *this; }
    myInt& operator ++() { ++value; return *this; }
    void show() {
        std::cout << value << std::endl;
    }
};

int main(int argc, char* argv[])
{
    myInt one(1);
    one.show();
    myInt two = ++(++one);
    two.show();
    one.show(); // Difference shows here!
    return 0;
}

This is because, without the reference, the ++ outside the parentheses operates on a locally-created copy of the one object.


问:
Object not found! The requested URL was not found on this server. localhost
I have a typical set up A,M,P and i am just doing some testing on my localhost server for setting up a webpage. I'm a bit new to php and dynamic sites so I'm muddling my way though. So I am at an impasse here. Whenever I attempt to view the page in the browser and click on the links I get this error:

Object not found!
The requested URL was not found on this server. The link on the referring page seems to be wrong or outdated. Please inform the author of that page about the error.
If you think this is a server error, please contact the webmaster.
Error 404
localhost
Apache/2.4.3 (Win32) OpenSSL/1.0.1c PHP/5.4.7

```<code>my url looks like this: http://localhost/test/content/home
</code>```

here is the code for my index.php page and my nav.php page

first index.php

```<code><?php
include('Config/setup.php');
?>
<?php
if(isset($_GET['page']) && $_GET['page'] == !'') {
    $pg = $_GET['page'];
} else {
    $pg = 'home';
}
#var_dump($pg);
#exit;
?>

<!DOCTYPE HTML>
<html>
<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">

    <title>FTS</title>
    <link href="css/Styles.css" rel="stylesheet" type="text/css">
</head>

<body>
<div class="header temp_Block">
    <?php include('templates/header.php');?>
</div>

<div class="main_nav temp_Block">
    <?php include('templates/main_nav.php');?>
</div>

<div class="main_Content temp_Block">
    <?php include('Content/'.$pg.'.php');?>
</div>

<div class="footer temp_Block">
    <?php include('templates/footer.php');?>
</div>
</body>
</html>
</code>```

Here is my nav.php

```<code><?php include('Config/setup.php')?>

 <a href="/test/content/home">home</a>
 <a href="/test/content/freestuff">free stuff</a>
 <a href="/test/content/aboutus">about us</a>
 <a href="/test/content/services">services</a>
 <a href="/test/content/Whatwedobetter">What we do better</a>
</code>```

I thought this might be a permissions problem because /content/home.php is in a subfolder in xxamp/htdocs/test. But I'm not entirely sure. I could test this on a hosting site which I have but the 404 error makes me think it might be something with localhost and not with my code.

答: One thing I found out is that your folder holding your php/html files cannot be named the same name as the folder in your HTDOCS carrying your project.</p>

Body:
I have a typical set up A,M,P and i am just doing some testing on my localhost server for setting up a webpage. I'm a bit new to php and dynamic sites so I'm muddling my way though. So I am at an impasse here. Whenever I attempt to view the page in the browser and click on the links I get this error:

Object not found!
The requested URL was not found on this server. The link on the referring page seems to be wrong or outdated. Please inform the author of that page about the error.
If you think this is a server error, please contact the webmaster.
Error 404
localhost
Apache/2.4.3 (Win32) OpenSSL/1.0.1c PHP/5.4.7

my url looks like this: http://localhost/test/content/home

here is the code for my index.php page and my nav.php page

first index.php

<?php
include('Config/setup.php');
?>
<?php
if(isset($_GET['page']) && $_GET['page'] == !'') {
    $pg = $_GET['page'];
} else {
    $pg = 'home';
}
#var_dump($pg);
#exit;
?>

<!DOCTYPE HTML>

    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">

    <title>FTS</title>
    <link href="css/Styles.css" rel="stylesheet" type="text/css">

    <?php include('templates/header.php');?>

    <?php include('templates/main_nav.php');?>

    <?php include('Content/'.$pg.'.php');?>

    <?php include('templates/footer.php');?>

Here is my nav.php

<?php include('Config/setup.php')?>

 home
 free stuff
 about us
 services
 What we do better

I thought this might be a permissions problem because /content/home.php is in a subfolder in xxamp/htdocs/test. But I'm not entirely sure. I could test this on a hosting site which I have but the 404 error makes me think it might be something with localhost and not with my code.


问:
How to activate rewrite URL from apache2 with Linux
I recently transfered all my websites from Windows to KUbuntu via virtual machine. And now I can't access a part of my website that is using rewrite URL...

I've already activated rewrite module with sudo a2enmod rewrite and AllowOverride in apache2 conf and restarted apache but that still does not work...

At the start, I got 404 errors (without default.conf AllowOverride things)
And now I've got a 500 internal error. How don't know how to proceed next, I Googled that problem, but nothing helped me.

EDIT: The 500 internal error happened from my .htaccess:

```<code>Header add Access-Control-Allow-Origin "*"
</code>```

My default.conf:

```<code><VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        <Directory /var/www/html>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride all
                Order allow,deny
                allow from all
                RewriteEngine on
        </Directory>
</VirtualHost>
</code>```

My .htaccess

```<code>Options -Indexes
RewriteEngine on
# RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
# %{HTTP_HOST} = domain
# %{REQUEST_URI} = /vl_web/...

# rewrite pages
RewriteRule ^login$  ./login.php [L]
RewriteRule ^reglement$  ./rules.php [L]
RewriteRule ^changelog$  ./changelog.php [L]
RewriteRule ^government/lspd/$  ./government/panel/?team=LSPD [L]
RewriteRule ^government/bcso/$  ./government/panel/?team=BCSO [L]

# 404 image
# RewriteRule \.(gif|jpe?g|png|bmp) ./assets/img/misc/404.png [NC,L]
# Ht Errors
ErrorDocument 404 /vl_web/assets/resources/hterr/index.php?error=404
ErrorDocument 403 /vl_web/assets/resources/hterr/index.php?error=403
ErrorDocument 500 /vl_web/assets/resources/hterr/index.php?error=500
ErrorDocument 503 /vl_web/assets/resources/hterr/index.php?error=503
</code>```

Any idea ?

答:
error in my .htaccess /var/www/html/vl_web/.htaccess: Invalid command 'Header', perhaps misspelled or defined by a module not included in the server configuration

Header is part of mod_headers, which needs to be _enabled. mod_headers is considered an "Extension", in other words:

A module with "Extension" status is not normally compiled and loaded into the server. To enable the module and its functionality, you may need to change the server build configuration files and re-compile Apache. (Source: https://httpd.apache.org/docs/current/mod/module-dict.html#Status)

Although, this will often just need "enabling" in the server config. (Requiring a webserver restart.)

php errors (that do not happen on windows so that's pretty weird): Undefined index: nom in /var/www/html/vl_web/government/panel/files/index/row2.php on line 35, referer: http://192.168.1.29/vl_web/government/

Differences in PHP versions and/or different (default) error_reporting levels could account for the differences in behaviour here. Notably, "Undefined index" messages became an E_WARNING in PHP 7 - previously this was an E_NOTICE.

'LimitInternalRecursion' errors: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace., referer: http://192.168.1.29/vl_web/

This is most probably caused by rewrites in your .htaccess file.

Please add the contents of your .htaccess file to you question.

Of note here is that Windows is a case-insenstive filesystem and Linux is not. The same directive might not match on Linux.

Aside:

```<code>    <Directory /var/www/html>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride all
            Order allow,deny
            allow from all
            RewriteEngine on
    </Directory>
</code>```

You probably want to disable MultiViews (you are explicitly enabling it above). If you are doing much with mod_rewrite (in .htaccess) then MultiViews can often result in conflicts (depends what you are doing).

Do you really want to enable directory Indexes?

Order and Allow are Apache 2.2 directives. You are evidentally on Apache 2.4 so should be using the Require directive instead.

You do not need to enable the RewriteEngine here unless you are using it in this scope (you are not). If you are using .htaccess then this will most probably override this anyway.

In other words, this should probably be written:

```<code>    <Directory /var/www/html>
            Options Indexes FollowSymLinks
            AllowOverride All
            Require all granted
    </Directory>
</code>```

Body:
I recently transfered all my websites from Windows to KUbuntu via virtual machine. And now I can't access a part of my website that is using rewrite URL...

I've already activated rewrite module with sudo a2enmod rewrite and AllowOverride in apache2 conf and restarted apache but that still does not work...

At the start, I got 404 errors (without default.conf AllowOverride things)
And now I've got a 500 internal error. How don't know how to proceed next, I Googled that problem, but nothing helped me.

EDIT: The 500 internal error happened from my .htaccess:

Header add Access-Control-Allow-Origin "*"

My default.conf:

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        <Directory /var/www/html>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride all
                Order allow,deny
                allow from all
                RewriteEngine on
        </Directory>
</VirtualHost>

My .htaccess

Options -Indexes
RewriteEngine on
# RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
# %{HTTP_HOST} = domain
# %{REQUEST_URI} = /vl_web/...

# rewrite pages
RewriteRule ^login$  ./login.php [L]
RewriteRule ^reglement$  ./rules.php [L]
RewriteRule ^changelog$  ./changelog.php [L]
RewriteRule ^government/lspd/$  ./government/panel/?team=LSPD [L]
RewriteRule ^government/bcso/$  ./government/panel/?team=BCSO [L]

# 404 image
# RewriteRule \.(gif|jpe?g|png|bmp) ./assets/img/misc/404.png [NC,L]
# Ht Errors
ErrorDocument 404 /vl_web/assets/resources/hterr/index.php?error=404
ErrorDocument 403 /vl_web/assets/resources/hterr/index.php?error=403
ErrorDocument 500 /vl_web/assets/resources/hterr/index.php?error=500
ErrorDocument 503 /vl_web/assets/resources/hterr/index.php?error=503

Any idea ?

Body:
error in my .htaccess /var/www/html/vl_web/.htaccess: Invalid command 'Header', perhaps misspelled or defined by a module not included in the server configuration

Header is part of mod_headers, which needs to be _enabled. mod_headers is considered an "Extension", in other words:

A module with "Extension" status is not normally compiled and loaded into the server. To enable the module and its functionality, you may need to change the server build configuration files and re-compile Apache. (Source: https://httpd.apache.org/docs/current/mod/module-dict.html#Status)

Although, this will often just need "enabling" in the server config. (Requiring a webserver restart.)

php errors (that do not happen on windows so that's pretty weird): Undefined index: nom in /var/www/html/vl_web/government/panel/files/index/row2.php on line 35, referer: http://192.168.1.29/vl_web/government/

Differences in PHP versions and/or different (default) error_reporting levels could account for the differences in behaviour here. Notably, "Undefined index" messages became an E_WARNING in PHP 7 - previously this was an E_NOTICE.

'LimitInternalRecursion' errors: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace., referer: http://192.168.1.29/vl_web/

This is most probably caused by rewrites in your .htaccess file.

Please add the contents of your .htaccess file to you question.

Of note here is that Windows is a case-insenstive filesystem and Linux is not. The same directive might not match on Linux.

Aside:

    <Directory /var/www/html>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride all
            Order allow,deny
            allow from all
            RewriteEngine on
    </Directory>

You probably want to disable MultiViews (you are explicitly enabling it above). If you are doing much with mod_rewrite (in .htaccess) then MultiViews can often result in conflicts (depends what you are doing).

Do you really want to enable directory Indexes?

Order and Allow are Apache 2.2 directives. You are evidentally on Apache 2.4 so should be using the Require directive instead.

You do not need to enable the RewriteEngine here unless you are using it in this scope (you are not). If you are using .htaccess then this will most probably override this anyway.

In other words, this should probably be written:

    <Directory /var/www/html>
            Options Indexes FollowSymLinks
            AllowOverride All
            Require all granted
    </Directory>


问:
Insert Multiple rows record Codeignite

A PHP Error was encountered Severity: Notice

Message: Undefined variable: stock

Filename: controllers/stock.php

Line Number: 28

Backtrace:

File: C:\xampp\htdocs\pharmacy\application\controllers\stock.php Line:
  28 Function: _error_handler

File: C:\xampp\htdocs\pharmacy\index.php Line: 315 Function:
  require_once

----this is my code----

```<code>public function save_stock($stock)
        {

                $supplier_name  =$this->input->post('cmb_supplier');
                $purchase_date  =$this->input->post('Txtdate');
                $invoice_number =$this->input->post('txtnumber');
                $med_name       =$this->input->post('product');
                $expiry_date    =$this->input->post('expiry');
                $qty            =$this->input->post('qty');
                $price          =$this->input->post('price');
                $cgst           =$this->input->post('tax_amount');
                $grand_total    =$this->input->post('total_amount');

            foreach ($supplier_name as $index => $supplier_name)
            {

                $supplier_name  =$supplier_name[$index];
                $purchase_date  =$purchase_date[$index];
                $invoice_number =$invoice_number[$index];
                $med_name       =$med_name[$index];
                $expiry_date    =$expiry_date[$index];
                $qty            =$qty[$index];
                $price          =$price[$index];
                $cgst           =$cgst[$index];
                $grand_total    =$grand_total[$index];

                    $stock[] = array(
                            'supplier_name'     =>$supplier_name,
                            'purchase_date'     =>$purchase_date,
                            'invoice_number'    =>$invoice_number,
                            'med_name'          =>$med_name,
                            'expiry_date'       =>$expiry_date,
                            'qty'               =>$qty,
                            'price'             =>$price,
                            'cgst'              =>$cgst,
                            'grand_total'       =>$grand_total
                    );
                    $this->db->insert("purchase_stock",$stock);
            }

        }
</code>```

答:
You did not define $stock as array out of the for loop. That is why you are getting the error.

Next, you need to user insert_batch instead of insert for multiple row inserts.

```<code>$stock = [];
foreach ($supplier_name as $index => $supplier_name)
        {

            $supplier_name  =$supplier_name[$index];
            $purchase_date  =$purchase_date[$index];
            $invoice_number =$invoice_number[$index];
            $med_name       =$med_name[$index];
            $expiry_date    =$expiry_date[$index];
            $qty            =$qty[$index];
            $price          =$price[$index];
            $cgst           =$cgst[$index];
            $grand_total    =$grand_total[$index];

                $stock[] = array(
                        'supplier_name'     =>$supplier_name,
                        'purchase_date'     =>$purchase_date,
                        'invoice_number'    =>$invoice_number,
                        'med_name'          =>$med_name,
                        'expiry_date'       =>$expiry_date,
                        'qty'               =>$qty,
                        'price'             =>$price,
                        'cgst'              =>$cgst,
                        'grand_total'       =>$grand_total
                );
                $this->db->insert_batch("purchase_stock",$stock);
        }
</code>```

Title: Insert Multiple rows record Codeignite

Body:
A PHP Error was encountered Severity: Notice

Message: Undefined variable: stock

Filename: controllers/stock.php

Line Number: 28

Backtrace:

File: C:\xampp\htdocs\pharmacy\application\controllers\stock.php Line:
  28 Function: _error_handler

File: C:\xampp\htdocs\pharmacy\index.php Line: 315 Function:
  require_once

----this is my code----

public function save_stock($stock)
        {

                $supplier_name  =$this->input->post('cmb_supplier');
                $purchase_date  =$this->input->post('Txtdate');
                $invoice_number =$this->input->post('txtnumber');
                $med_name       =$this->input->post('product');
                $expiry_date    =$this->input->post('expiry');
                $qty            =$this->input->post('qty');
                $price          =$this->input->post('price');
                $cgst           =$this->input->post('tax_amount');
                $grand_total    =$this->input->post('total_amount');

            foreach ($supplier_name as $index => $supplier_name)
            {

                $supplier_name  =$supplier_name[$index];
                $purchase_date  =$purchase_date[$index];
                $invoice_number =$invoice_number[$index];
                $med_name       =$med_name[$index];
                $expiry_date    =$expiry_date[$index];
                $qty            =$qty[$index];
                $price          =$price[$index];
                $cgst           =$cgst[$index];
                $grand_total    =$grand_total[$index];

                    $stock[] = array(
                            'supplier_name'     =>$supplier_name,
                            'purchase_date'     =>$purchase_date,
                            'invoice_number'    =>$invoice_number,
                            'med_name'          =>$med_name,
                            'expiry_date'       =>$expiry_date,
                            'qty'               =>$qty,
                            'price'             =>$price,
                            'cgst'              =>$cgst,
                            'grand_total'       =>$grand_total
                    );
                    $this->db->insert("purchase_stock",$stock);
            }

        }

Body:
You did not define $stock as array out of the for loop. That is why you are getting the error.

Next, you need to user insert_batch instead of insert for multiple row inserts.

$stock = [];
foreach ($supplier_name as $index => $supplier_name)
        {

            $supplier_name  =$supplier_name[$index];
            $purchase_date  =$purchase_date[$index];
            $invoice_number =$invoice_number[$index];
            $med_name       =$med_name[$index];
            $expiry_date    =$expiry_date[$index];
            $qty            =$qty[$index];
            $price          =$price[$index];
            $cgst           =$cgst[$index];
            $grand_total    =$grand_total[$index];

                $stock[] = array(
                        'supplier_name'     =>$supplier_name,
                        'purchase_date'     =>$purchase_date,
                        'invoice_number'    =>$invoice_number,
                        'med_name'          =>$med_name,
                        'expiry_date'       =>$expiry_date,
                        'qty'               =>$qty,
                        'price'             =>$price,
                        'cgst'              =>$cgst,
                        'grand_total'       =>$grand_total
                );
                $this->db->insert_batch("purchase_stock",$stock);
        }


问:
Tour of Go exercise #10: Crawler
I'm going through the Go Tour and I feel like I have a pretty good understanding of the language except for concurrency.

slide 10 is an exercise that asks the reader to parallelize a web crawler (and to make it not cover repeats but I haven't gotten there yet.)

Here is what I have so far:

```<code>func Crawl(url string, depth int, fetcher Fetcher, ch chan string) {
    if depth <= 0 {
        return
    }

    body, urls, err := fetcher.Fetch(url)
    if err != nil {
        ch <- fmt.Sprintln(err)
        return
    }

    ch <- fmt.Sprintf("found: %s %q\n", url, body)
    for _, u := range urls {
        go Crawl(u, depth-1, fetcher, ch)
    }
}

func main() {
    ch := make(chan string, 100)
    go Crawl("http://golang.org/", 4, fetcher, ch)

    for i := range ch {
        fmt.Println(i)
    }
}
</code>```

My question is, where do I put the close(ch) call.

If I put a defer close(ch) somewhere in the Crawl method, then the program ends up writing to a closed channel from one of the spawned goroutines, because the call to Crawl will return before the spawned goroutines do.

If I omit the call to close(ch), as I demonstrate it, the program deadlocks in the main function ranging the channel because the channel is never closed when all goroutines has returned.

答:
Here is my solution :)</p>

```<code>package main

import (
    "fmt"
    "runtime"
    "sync"
)

type Fetcher interface {
    // Fetch returns the body of URL and
    // a slice of URLs found on that page.
    Fetch(url string) (body string, urls []string, err error)
}

// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher, set map[string]bool) {
    // TODO: Fetch URLs in parallel.
    // TODO: Don't fetch the same URL twice.
    // This implementation doesn't do either:
    if depth <= 0 {
        return
    }
    // use a set to identify if the URL should be traversed or not
    if set[url] == true {
        wg.Done()
        return
    } else {
        fmt.Println(runtime.NumGoroutine())
        set[url] = true
        body, urls, err := fetcher.Fetch(url)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Printf("found: %s %q\n", url, body)
        for _, u := range urls {
            Crawl(u, depth-1, fetcher, set)
        }

    }

}

var wg sync.WaitGroup

func main() {
    wg.Add(6)
    collectedURLs := make(map[string]bool)
    go Crawl("https://golang.org/", 4, fetcher, collectedURLs)
    wg.Wait()
}

// fakeFetcher is Fetcher that returns canned results.
type fakeFetcher map[string]*fakeResult

type fakeResult struct {
    body string
    urls []string
}

func (f fakeFetcher) Fetch(url string) (string, []string, error) {
    if res, ok := f[url]; ok {
        return res.body, res.urls, nil
    }
    return "", nil, fmt.Errorf("not found: %s", url)
}

// fetcher is a populated fakeFetcher.
var fetcher = fakeFetcher{
    "https://golang.org/": &fakeResult{
        "The Go Programming Language",
        []string{
            "https://golang.org/pkg/",
            "https://golang.org/cmd/",
        },
    },
    "https://golang.org/pkg/": &fakeResult{
        "Packages",
        []string{
            "https://golang.org/",
            "https://golang.org/cmd/",
            "https://golang.org/pkg/fmt/",
            "https://golang.org/pkg/os/",
        },
    },
    "https://golang.org/pkg/fmt/": &fakeResult{
        "Package fmt",
        []string{
            "https://golang.org/",
            "https://golang.org/pkg/",
        },
    },
    "https://golang.org/pkg/os/": &fakeResult{
        "Package os",
        []string{
            "https://golang.org/",
            "https://golang.org/pkg/",
        },
    },
}
</code>```

Title: Tour of Go exercise #10: Crawler

Body:
I'm going through the Go Tour and I feel like I have a pretty good understanding of the language except for concurrency.

slide 10 is an exercise that asks the reader to parallelize a web crawler (and to make it not cover repeats but I haven't gotten there yet.)

Here is what I have so far:

func Crawl(url string, depth int, fetcher Fetcher, ch chan string) {
    if depth <= 0 {
        return
    }

    body, urls, err := fetcher.Fetch(url)
    if err != nil {
        ch <- fmt.Sprintln(err)
        return
    }

    ch <- fmt.Sprintf("found: %s %q\n", url, body)
    for _, u := range urls {
        go Crawl(u, depth-1, fetcher, ch)
    }
}

func main() {
    ch := make(chan string, 100)
    go Crawl("http://golang.org/", 4, fetcher, ch)

    for i := range ch {
        fmt.Println(i)
    }
}

My question is, where do I put the close(ch) call.

If I put a defer close(ch) somewhere in the Crawl method, then the program ends up writing to a closed channel from one of the spawned goroutines, because the call to Crawl will return before the spawned goroutines do.

If I omit the call to close(ch), as I demonstrate it, the program deadlocks in the main function ranging the channel because the channel is never closed when all goroutines has returned.

Body:
Here is my solution :)

package main

import (
    "fmt"
    "runtime"
    "sync"
)

type Fetcher interface {
    // Fetch returns the body of URL and
    // a slice of URLs found on that page.
    Fetch(url string) (body string, urls []string, err error)
}

// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher, set map[string]bool) {
    // TODO: Fetch URLs in parallel.
    // TODO: Don't fetch the same URL twice.
    // This implementation doesn't do either:
    if depth <= 0 {
        return
    }
    // use a set to identify if the URL should be traversed or not
    if set[url] == true {
        wg.Done()
        return
    } else {
        fmt.Println(runtime.NumGoroutine())
        set[url] = true
        body, urls, err := fetcher.Fetch(url)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Printf("found: %s %q\n", url, body)
        for _, u := range urls {
            Crawl(u, depth-1, fetcher, set)
        }

    }

}

var wg sync.WaitGroup

func main() {
    wg.Add(6)
    collectedURLs := make(map[string]bool)
    go Crawl("https://golang.org/", 4, fetcher, collectedURLs)
    wg.Wait()
}

// fakeFetcher is Fetcher that returns canned results.
type fakeFetcher map[string]*fakeResult

type fakeResult struct {
    body string
    urls []string
}

func (f fakeFetcher) Fetch(url string) (string, []string, error) {
    if res, ok := f[url]; ok {
        return res.body, res.urls, nil
    }
    return "", nil, fmt.Errorf("not found: %s", url)
}

// fetcher is a populated fakeFetcher.
var fetcher = fakeFetcher{
    "https://golang.org/": &fakeResult{
        "The Go Programming Language",
        []string{
            "https://golang.org/pkg/",
            "https://golang.org/cmd/",
        },
    },
    "https://golang.org/pkg/": &fakeResult{
        "Packages",
        []string{
            "https://golang.org/",
            "https://golang.org/cmd/",
            "https://golang.org/pkg/fmt/",
            "https://golang.org/pkg/os/",
        },
    },
    "https://golang.org/pkg/fmt/": &fakeResult{
        "Package fmt",
        []string{
            "https://golang.org/",
            "https://golang.org/pkg/",
        },
    },
    "https://golang.org/pkg/os/": &fakeResult{
        "Package os",
        []string{
            "https://golang.org/",
            "https://golang.org/pkg/",
        },
    },
}


问:
How to create dynamic routes that start with a specific character in Next.js?
I want to create routes that start with @ symbol how should I structure the pages folder?
first I tried to create a folder with @ as its name however it will create routes that proceed with @ like www.example.com/@/something. I even tried [@topic] and @[topic] names for folders but it does not work as expected.

I want to have routes like:
www.example.com/@computer
www.example.com/@music
www.example.com/@programming

how can I approach the problem?

My Next.js version is 9.2.1

答:
As @Nico mentioned, We can approach the solution with inspiring from custom-server example in Next.js repo.

Page's structure will be like this: page->[topic]

We need to check inside server.js for any incoming request with URL that starts with @ symbol, to do so we'll get help regular expressions inside express.js:

```<code>const express = require('express')
const next = require('next')

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
    const server = express()

    // this will match all the URLs that start with @
    // e.g. @computer, @hello
    server.get('/@*', (req, res) => {
        return app.render(req, res, '/[topic]', req.query)
    })

    server.all('*', (req, res) => {
        return handle(req, res)
    })

    server.listen(port, err => {
        if (err) throw err
            console.log(`> Ready on http://localhost:${port}`)
    })
})
</code>```

This simply coordinates requests that start with @ to [topic] component as before as handling other routes.

Inside component for client-side it is as simple as this:

```<code> <Link href="/[topic]" as=`@${topicString}`/>
</code>```

You can get topicString in different ways like using query inside getInitialProps

Body:
As @Nico mentioned, We can approach the solution with inspiring from custom-server example in Next.js repo.

Page's structure will be like this: page->[topic]

We need to check inside server.js for any incoming request with URL that starts with @ symbol, to do so we'll get help regular expressions inside express.js:

const express = require('express')
const next = require('next')

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
    const server = express()

    // this will match all the URLs that start with @
    // e.g. @computer, @hello
    server.get('/@*', (req, res) => {
        return app.render(req, res, '/[topic]', req.query)
    })

    server.all('*', (req, res) => {
        return handle(req, res)
    })

    server.listen(port, err => {
        if (err) throw err
            console.log(`> Ready on http://localhost:${port}`)
    })
})

This simply coordinates requests that start with @ to [topic] component as before as handling other routes.

Inside component for client-side it is as simple as this:

 <Link href="/[topic]" as=`@${topicString}`/>

You can get topicString in different ways like using query inside getInitialProps


问:
WordPress twentytwenty theme child css not effective
I followed all the instructions to create my child theme. In functions.php, I have:

```<code><?php

    add_action( 'wp_enqueue_scripts', 'tt_child_enqueue_parent_styles' );

    function tt_child_enqueue_parent_styles() {
       wp_enqueue_style( 'parent-style', get_template_directory_uri().'/style.css' );
    }

?>
</code>```

In style.css, i have correct header comment part:

```<code>/*
 Theme Name:   Twenty Twenty Child
 Theme URI:    http://example.com/twenty-twenty-child/
 Description:  Twenty Twenty Child Theme
 Author:       X Y
 Author URI:   http://example.com
 Template:     twentytwenty
 Version:      1.0
 License:      GNU General Public License v2 or later
 License URI:  http://www.gnu.org/licenses/gpl-2.0.html
 Tags:         light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready
 Text Domain:  twentytwentychild
*/

h1 {
    visibility: hidden;
}
</code>```

However, seems the child style.css don't work, no effect. In the page HTML code, below lines show and look correct:

```<code><link rel='stylesheet' id='parent-style-css'  href='https://lifepromise.co.uk/wp-content/themes/twentytwenty/style.css' media='all' />
<link rel='stylesheet' id='twentytwenty-style-css'  href='https://lifepromise.co.uk/wp-content/themes/twentytwenty-child/style.css' media='all' />
</code>```

答:
Try this code on function.php

```<code>add_action( 'wp_enqueue_scripts', 'tt_child_enqueue_parent_styles' );

function tt_child_enqueue_parent_styles() {
   wp_enqueue_style( 'twentytwenty-style', get_template_directory_uri().'/style.css' );
   wp_enqueue_style( 'child-style', get_stylesheet_directory_uri().'/style.css', array('twentytwenty-style') );
}
</code>```

Tested and working

Body:
I followed all the instructions to create my child theme. In functions.php, I have:

<?php

    add_action( 'wp_enqueue_scripts', 'tt_child_enqueue_parent_styles' );

    function tt_child_enqueue_parent_styles() {
       wp_enqueue_style( 'parent-style', get_template_directory_uri().'/style.css' );
    }

?>

In style.css, i have correct header comment part:

/*
 Theme Name:   Twenty Twenty Child
 Theme URI:    http://example.com/twenty-twenty-child/
 Description:  Twenty Twenty Child Theme
 Author:       X Y
 Author URI:   http://example.com
 Template:     twentytwenty
 Version:      1.0
 License:      GNU General Public License v2 or later
 License URI:  http://www.gnu.org/licenses/gpl-2.0.html
 Tags:         light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready
 Text Domain:  twentytwentychild
*/

h1 {
    visibility: hidden;
}

However, seems the child style.css don't work, no effect. In the page HTML code, below lines show and look correct:

<link rel='stylesheet' id='parent-style-css'  href='https://lifepromise.co.uk/wp-content/themes/twentytwenty/style.css' media='all' />
<link rel='stylesheet' id='twentytwenty-style-css'  href='https://lifepromise.co.uk/wp-content/themes/twentytwenty-child/style.css' media='all' />

Body:
Try this code on function.php

add_action( 'wp_enqueue_scripts', 'tt_child_enqueue_parent_styles' );

function tt_child_enqueue_parent_styles() {
   wp_enqueue_style( 'twentytwenty-style', get_template_directory_uri().'/style.css' );
   wp_enqueue_style( 'child-style', get_stylesheet_directory_uri().'/style.css', array('twentytwenty-style') );
}

Tested and working


问:
How to align mat-button with mat-input?
How can I get these two items to align properly? I am trying to get them perfectly aligned but adjusting the button height just makes the bottom have get further away from the bottom of the search input. I think its because the center of them are not aligned so adjusting the height isn't really the correct solution.

Here's the HTML

```<code><!-- Search Box and Button-->
    <p>Search by company name:</p>
    <mat-form-field appearance="outline">
        <mat-label>Search</mat-label>
        <input matInput placeholder="Search">
    </mat-form-field>

    <button mat-stroked-button color="primary">Search</button>
</code>```

Here's the SCSS:

```<code>mat-form-field.mat-form-field {
    font-size: 12px;
    width: 300px;
  }

  button.mat-stroked-button {
    font-size: 14px;
    height: 42px;
    margin: 10px;
  }
</code>```

答:
To achieve horizontal alignment you need to make some adjustment in markup and use flex properties for perfect alignment. I have added few div as parent but if you want you can assign CSS to actual parent classes of your code. I have added my snippet code below, update HTML and CSS accordingly :

.searchcontainer {
          text-align:center;
          width: 100%;
          max-width: 600px;
          margin: 0 auto;
       }

       .searchcontainer .search-part {
          display: flex;
          flex-direction: row;
          justify-content: center;
          align-items: center;
       }

      mat-form-field.mat-form-field {
          font-size: 12px;
          width: 300px;
      }

      button.mat-stroked-button {
          font-size: 14px;
          height: 42px;
          margin: 10px;
      }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="searchcontainer">

      <p>Search by company name:</p>

      <div class="search-part">

        <mat-form-field appearance="outline">
            <mat-label>Search</mat-label>
            <input matInput placeholder="Search">
        </mat-form-field>

        <button mat-stroked-button color="primary">Search</button>
      </div>

    </div></code>```

Title: How to align mat-button with mat-input?

Body:
How can I get these two items to align properly? I am trying to get them perfectly aligned but adjusting the button height just makes the bottom have get further away from the bottom of the search input. I think its because the center of them are not aligned so adjusting the height isn't really the correct solution.

Here's the HTML

Search by company name:

    <mat-form-field appearance="outline">
        <mat-label>Search</mat-label>
        <input matInput placeholder="Search">
    </mat-form-field>

    <button mat-stroked-button color="primary">Search</button>

Here's the SCSS:

mat-form-field.mat-form-field {
    font-size: 12px;
    width: 300px;
  }

  button.mat-stroked-button {
    font-size: 14px;
    height: 42px;
    margin: 10px;
  }

Body:
To achieve horizontal alignment you need to make some adjustment in markup and use flex properties for perfect alignment. I have added few div as parent but if you want you can assign CSS to actual parent classes of your code. I have added my snippet code below, update HTML and CSS accordingly :

.searchcontainer {
          text-align:center;
          width: 100%;
          max-width: 600px;
          margin: 0 auto;
       }

       .searchcontainer .search-part {
          display: flex;
          flex-direction: row;
          justify-content: center;
          align-items: center;
       }

      mat-form-field.mat-form-field {
          font-size: 12px;
          width: 300px;
      }

      button.mat-stroked-button {
          font-size: 14px;
          height: 42px;
          margin: 10px;
      }

<div class="searchcontainer">

      <p>Search by company name:</p>

      <div class="search-part">

        <mat-form-field appearance="outline">
            <mat-label>Search</mat-label>
            <input matInput placeholder="Search">
        </mat-form-field>

        <button mat-stroked-button color="primary">Search</button>
      </div>

    </div>


问:
Best way to wait for .forEach() to complete
Sometimes I need to wait for a .forEach() method to finish, mostly on 'loader' functions. This is the way I do that:

```<code>$q.when(array.forEach(function(item){
    //iterate on something
})).then(function(){
    //continue with processing
});
</code>```

I can't help but feel that this isn't the best way to wait for a .forEach() to finish. What is the best way to do this?

答:
Alter and check a counter at the end of every possible unique branch of code, including callbacks. Example:

const fs = require('fs');

/**
 * @description Delete files older than 1 day
 * @param {String} directory - The directory to purge
 * @return {Promise}
 */
async function purgeFiles(directory) {
  const maxAge = 24*3600000;
  const now = Date.now();
  const cutoff = now-maxAge;

  let filesPurged = 0;
  let filesProcessed = 0;
  let purgedSize = 0;

  await new Promise( (resolve, reject) => {
    fs.readdir(directory, (err, files) => {
      if (err) {
        return reject(err);
      }
      if (!files.length) {
        return resolve();
      }
      files.forEach( file => {
        const path = `${directory}/${file}`;
        fs.stat(path, (err, stats)=> {
          if (err) {
            console.log(err);
            if (++filesProcessed === files.length) resolve();
          }
          else if (stats.isFile() && stats.birthtimeMs < cutoff) {
            const ageSeconds = parseInt((now-stats.birthtimeMs)/1000);
            fs.unlink(path, error => {
              if (error) {
                console.log(`Deleting file failed: ${path} ${error}`);
              }
              else {
                ++filesPurged;
                purgedSize += stats.size;
                console.log(`Deleted file with age ${ageSeconds} seconds: ${path}`);
              }
              if (++filesProcessed === files.length) resolve();
            });
          }
          else if (++filesProcessed === files.length) resolve();
        });
      });
    });
  });

  console.log(JSON.stringify({
    directory,
    filesProcessed,
    filesPurged,
    purgedSize,
  }));
}

// !!DANGER!! Change this line! (intentional syntax error in ,')
const directory = ,'/tmp'; // !!DANGER!! Changeme
purgeFiles(directory).catch(error=>console.log(error));
```

Body:
Sometimes I need to wait for a .forEach() method to finish, mostly on 'loader' functions. This is the way I do that:

$q.when(array.forEach(function(item){
    //iterate on something
})).then(function(){
    //continue with processing
});

I can't help but feel that this isn't the best way to wait for a .forEach() to finish. What is the best way to do this?


问:
AWS Cognito - Use Refresh Token immediately after login
I want to force-refresh the AWS cognito token in the client, so that as soon as a user logs in the app immediately uses the refresh token to get a new access token (with longer exp time). I've read about initiateAuth and cognitoUser.refreshSession() methods, but I'm not sure which one I need to use? I'm trying the below method and I am getting a new token back but it's always just valid for 1 more hour (at least that is what I see when I check the exp time on the token). I want to get a token that is valid for 30 days (which is what I have configured in cognito). Any help will be greatly appreciated!

  const getTokens = function(session) {
    return {
      accessToken: session.getAccessToken(),
      idToken: session.getIdToken(),
      refreshToken: session.getRefreshToken()
 };

  cognitoUser.refreshSession(refreshToken, (err, session) => {
  if (err) {
   console.log(err);
  } else {
        const tokens = getTokens(session);
   console.log(tokens);
      localStorage.setItem("sessionTokens", JSON.stringify(tokens));
    }
  }```

答:
The ID and Access token in Cognito are valid for 1 hour and this is not configurable. You mentioned you have configured the tokens to last for 30 days, this is the validity/expiry time of your refresh tokens.
Calling certain methods on the client side SDKs (Amplify or identity SDK) will automatically check the validity and expiry time of the tokens and refresh them if needed.

This has now changed as can be seen here:
https://aws.amazon.com/about-aws/whats-new/2020/08/amazon-cognito-user-pools-supports-customization-of-token-expiration/