问:
Xamarin Forms: TemplatedItems returns only viewcells from grouped headings
I need to get all the viewcells of my listview programmatically so I could change the background color of a specific child layout within the viewcell.
There's no problem with updating the color for a viewcell when it's tapped, but I need to change the color of all viewcells to the default color, whenever a different viewcell is tapped.

While searching for a solution I often found answers where the viewcells were accessed by the runtime properties of the listview (see code below or the second answer in here: Xamarin.Forms: Get all cells/items of a listview), while testing the code I realized that this doesn't work for listviews where grouping is enabled.

```<code>IEnumerable<PropertyInfo> pInfos = (connectionsListView as ItemsView<Cell>).GetType().GetRuntimeProperties();
var templatedItems = pInfos.FirstOrDefault(info => info.Name == "TemplatedItems");
if (templatedItems != null)
{
  var cells = templatedItems.GetValue(connectionsListView);
    foreach (ViewCell cell in cells as Xamarin.Forms.ITemplatedItemsList<Xamarin.Forms.Cell>)
    {
        if (cell.BindingContext != null && cell.BindingContext is MyModelClass)
        {
              // Change background color of viewcell
        }
    }
}
</code>```

When grouping is enabled this code only returns the grouped header viewcells. I couldn't find any answer to change this code so the actual "body" viewcells are returned instead of only the headings.
Is there any possible approach to change this code so I get my expected result or do I have to use a custom renderer for this?

Update - Listview xaml code

Here you can see the listview I'm currently using in my XAML. I try to work out a solution where I can bind the background color of each viewcell to the model (to each "document" in my case) but at the moment I couldn't work out how to change the color for each specific viewcell when one is tapped. (I need to only have the background color of the currently selected viewcell to be changed, so all other viewcells have the default background color.)

```<code>            <ListView x:Name="DocumentListView"
                      ItemsSource="{Binding GroupedDocuments}"
                      BackgroundColor="WhiteSmoke"
                      HasUnevenRows="True"
                      RefreshCommand="{Binding LoadDocumentsCommand}"
                      IsPullToRefreshEnabled="True"
                      Refreshing="DocumentListView_OnRefreshing"
                      IsRefreshing="{Binding IsBusy, Mode=OneWay}"
                      CachingStrategy="RecycleElement"
                      IsGroupingEnabled="True"
                      GroupDisplayBinding="{Binding Key}"
                      GroupShortNameBinding="{Binding Key}"
                      VerticalOptions="StartAndExpand"
                      HorizontalOptions="StartAndExpand"
                      Margin="0, -20, 0, 0">
                <ListView.GroupHeaderTemplate>
                    <DataTemplate>
                        <ViewCell Height="25">
                            <Label x:Name="DocumentDate"
                                   FontSize="Medium"
                                   TextColor="#2E588C"
                                   VerticalOptions="Center"
                                   HorizontalTextAlignment="Center"
                                   Text="{Binding Key}"/>
                        </ViewCell>
                    </DataTemplate>
                </ListView.GroupHeaderTemplate>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell Height="155" Tapped="DocumentViewCell_OnTapped">
                            <StackLayout Padding="10, 5, 10, 5">
                                <Frame Padding="0" HorizontalOptions="FillAndExpand" HasShadow="True">
                                    <StackLayout Padding="10" Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand">
                                        <StackLayout HorizontalOptions="StartAndExpand">
                                            <StackLayout Orientation="Horizontal" Spacing="15" Margin="10, 10, 10, 0" HorizontalOptions="StartAndExpand">
                                                <Label Text="{Binding Name}"
                                                       LineBreakMode="NoWrap"
                                                       FontSize="20"
                                                       TextColor="CornflowerBlue"
                                                       FontAttributes="Bold"/>
                                            </StackLayout>
                                            <StackLayout Orientation="Horizontal" Spacing="5" Margin="12, 0, 0, 0" HorizontalOptions="StartAndExpand">
                                                <Label Text="{Binding DocumentType.Name, StringFormat='Typ: {0}'}"
                                                       LineBreakMode="NoWrap"
                                                       FontSize="16"
                                                       TextColor="Black"/>
                                            </StackLayout>
                                            <StackLayout Orientation="Horizontal" Spacing="5" Margin="12, 3, 0, 0" HorizontalOptions="StartAndExpand">
                                                <Label Text="{Binding TotalValue, StringFormat='Gesamtwert: {0:F2} €'}"
                                                       LineBreakMode="NoWrap"
                                                       FontSize="16"
                                                       TextColor="Black"/>
                                            </StackLayout>
                                            <StackLayout Spacing="5" Margin="12, 3, 0, 0" Orientation="Horizontal" HorizontalOptions="StartAndExpand" VerticalOptions="Start">
                                                <Label Text="{Binding TagCollectionString, StringFormat='Tags: {0}'}"
                                                       LineBreakMode="WordWrap"
                                                       FontSize="14"
                                                       TextColor="Black"
                                                       VerticalOptions="CenterAndExpand"/>
                                            </StackLayout>
                                        </StackLayout>
                                        <StackLayout HorizontalOptions="EndAndExpand" VerticalOptions="Start" Margin="0, 25, 25, 0">
                                            <ImageButton HeightRequest="85" MinimumWidthRequest="85" x:Name="ButtonEditDocument" Source="baseline_more_vert_black_48.png" Clicked="ButtonEditDocument_OnClicked" Margin="0, 0, 15, 0" BackgroundColor="Transparent" WidthRequest="25" />
                                        </StackLayout>
                                    </StackLayout>
                                </Frame>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
</code>```

Update 2 - Usage of Bindings

I worked out how I could use bindings to store the currently selected background of each viewcell in my model. At the moment I'm facing the issue that the UI doesn't update properly when the bound values have changed.
Here is the code I have written so far and how the page is updated when a different viewcell is tapped:

Document model class:

```<code>public class Document
{
        public bool HasDefaultColor { get; set; }

        public string CurrentlySelectedColorFromHex
        {
            get => ColorConverter.GetHexString(CurrentlySelectedColor);
        }

        [NotMapped]
        public Color CurrentlySelectedColor => HasDefaultColor ? DefaultColor : ActivatedColor;

        private static readonly Color DefaultColor = Color.WhiteSmoke;
        private static readonly Color ActivatedColor = Color.FromHex("#2E588C");
}
</code>```

OnTapped function in code-behind:

```<code>        private void DocumentViewCell_OnTapped(object sender, EventArgs e)
        {
                    var documents = documentRepository.GetAll();
                    foreach (var document in documents)
                        document.HasDefaultColor = true;

                    selectedDocument.HasDefaultColor = false;
                    unitOfWork.Complete();
                    UpdatePage();
}
</code>```

In UpdatePage() I want to refresh the listview properly after the bound collection has changed:

```<code>                viewModel.LoadDocuments();
                DocumentListView.BeginRefresh();
</code>```

Sorry if this is a beginner question but I couldn't find an answer to this yet or couldn't figure out how to properly update the UI so that the background color of each viewcell is properly updated.
At least the bounded values are stored correctly at each OnTapped() call.

Update 3 - Added Converter

Hey guys, I have tried a few things and get stuck with updating the bound property of the model.
I have tried data triggers as well but couldn't change those data triggers correctly so they didn't worked as I expected them to do.

Until now I have added a custom bool to Color converter to convert the bound property:

```<code>    public class BoolToColorConverter : IValueConverter
    {
        private static readonly Color DefaultColor = Color.WhiteSmoke;
        private static readonly Color ActivatedColor = Color.FromHex("#2E588C");

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool activated)
                return activated ? ActivatedColor : DefaultColor;

            return DefaultColor;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is Color color)
            {
                if (color == DefaultColor)
                    return true;
            }

            return false;
        }
</code>```

The Color converter returns the correct values, but I can't figure out how to update the model property at runtime in the OnTapped() method of each viewcell.

Currently this is my OnTapped() method:

```<code>        private void DocumentViewCell_OnTapped(object sender, EventArgs e)
        {
                // Determine which document was selected
                if (sender.GetType() == typeof(ViewCell))
                {
                    ViewCell selectedViewCell = (ViewCell)sender;

                    if (selectedViewCell.BindingContext != null && selectedViewCell.BindingContext.GetType() == typeof(Document))
                    {
                        Document document = (Document)selectedViewCell.BindingContext;

                        // Update backing field selectedDocument for correct bindings and to show correct detail page
                        if (document != null)
                            selectedDocument = document;
                    }
                }
</code>```

Thanks for any help in advance and thanks to anyone who commented so far.

答:
(See the answer which @Knoop gave for doing it in the right way with correct xamarin forms bindings and commands)

As I could accomplish my initial goal, which was to change the background color of each viewcell programmatically in code behind, I will post my result as an answer.

At first I learned that iterating over the viewcells is a bad idea because it's against the design pattern. So I used bindings, as well as a custom BoolToColor Converter to dynamically update the viewcells background color.

This is the code I have written:

Model class (Document):

```<code>   public class Document : BaseModel<int>, IDocument, INotifyPropertyChanged
    {
        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var changed = PropertyChanged;

            changed?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion // INotifyPropertyChanged

        public bool HasDefaultColor
        {
            get => hasDefaultColor;
            set
            {
                hasDefaultColor = value;
                OnPropertyChanged();
            }
        }
    }
</code>```

The converter

```<code>public class BoolToColorConverter : IValueConverter (see question for detailed code...)
</code>```

The implementation of the converter in xaml:

```<code><Frame BackgroundColor="{Binding HasDefaultColor, Converter={converters:BoolToColorConverter}}"  Padding="0" HorizontalOptions="FillAndExpand" HasShadow="True">
</code>```

And finally (which was the part where I got stuck with), properly updating the collection in the binded viewmodel in the OnTapped() method:

```<code>        private void DocumentViewCell_OnTapped(object sender, EventArgs e)
        {
            try
            {
                // Determine which document was selected
                if (sender.GetType() == typeof(ViewCell))
                {
                    ViewCell selectedViewCell = (ViewCell)sender;

                    if (selectedViewCell.BindingContext != null && selectedViewCell.BindingContext.GetType() == typeof(Document))
                    {
                        Document document = (Document)selectedViewCell.BindingContext;

                        if (document != null)
                        {
                            // Update default color (viewcell) for binded model
                            document.HasDefaultColor = !document.HasDefaultColor;

                            // Update backing field selectedDocument for correct bindings and to show correct detail page

                            ObservableCollection<Grouping<string, Document>> documents = viewModel.GroupedDocuments;
                            foreach (var group in documents)
                            {
                                foreach (var doc in group)
                                {
                                    if (doc.Name == document.Name)
                                    {
                                        doc.HasDefaultColor = document.HasDefaultColor;
                                    }
                                }
                            }

                            viewModel.GroupedDocuments = documents;
                            selectedDocument = document;
                        }
                    }
               }
           }
       }
</code>```

Body:
I need to get all the viewcells of my listview programmatically so I could change the background color of a specific child layout within the viewcell.
There's no problem with updating the color for a viewcell when it's tapped, but I need to change the color of all viewcells to the default color, whenever a different viewcell is tapped.

While searching for a solution I often found answers where the viewcells were accessed by the runtime properties of the listview (see code below or the second answer in here: Xamarin.Forms: Get all cells/items of a listview), while testing the code I realized that this doesn't work for listviews where grouping is enabled.

IEnumerable<PropertyInfo> pInfos = (connectionsListView as ItemsView<Cell>).GetType().GetRuntimeProperties();
var templatedItems = pInfos.FirstOrDefault(info => info.Name == "TemplatedItems");
if (templatedItems != null)
{
  var cells = templatedItems.GetValue(connectionsListView);
    foreach (ViewCell cell in cells as Xamarin.Forms.ITemplatedItemsList<Xamarin.Forms.Cell>)
    {
        if (cell.BindingContext != null && cell.BindingContext is MyModelClass)
        {
              // Change background color of viewcell
        }
    }
}

When grouping is enabled this code only returns the grouped header viewcells. I couldn't find any answer to change this code so the actual "body" viewcells are returned instead of only the headings.
Is there any possible approach to change this code so I get my expected result or do I have to use a custom renderer for this?

Update - Listview xaml code

Here you can see the listview I'm currently using in my XAML. I try to work out a solution where I can bind the background color of each viewcell to the model (to each "document" in my case) but at the moment I couldn't work out how to change the color for each specific viewcell when one is tapped. (I need to only have the background color of the currently selected viewcell to be changed, so all other viewcells have the default background color.)

            <ListView x:Name="DocumentListView"
                      ItemsSource="{Binding GroupedDocuments}"
                      BackgroundColor="WhiteSmoke"
                      HasUnevenRows="True"
                      RefreshCommand="{Binding LoadDocumentsCommand}"
                      IsPullToRefreshEnabled="True"
                      Refreshing="DocumentListView_OnRefreshing"
                      IsRefreshing="{Binding IsBusy, Mode=OneWay}"
                      CachingStrategy="RecycleElement"
                      IsGroupingEnabled="True"
                      GroupDisplayBinding="{Binding Key}"
                      GroupShortNameBinding="{Binding Key}"
                      VerticalOptions="StartAndExpand"
                      HorizontalOptions="StartAndExpand"
                      Margin="0, -20, 0, 0">
                <ListView.GroupHeaderTemplate>
                    <DataTemplate>
                        <ViewCell Height="25">

                        </ViewCell>
                    </DataTemplate>
                </ListView.GroupHeaderTemplate>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell Height="155" Tapped="DocumentViewCell_OnTapped">
                            <StackLayout Padding="10, 5, 10, 5">
                                <Frame Padding="0" HorizontalOptions="FillAndExpand" HasShadow="True">
                                    <StackLayout Padding="10" Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand">
                                        <StackLayout HorizontalOptions="StartAndExpand">
                                            <StackLayout Orientation="Horizontal" Spacing="15" Margin="10, 10, 10, 0" HorizontalOptions="StartAndExpand">

                                            </StackLayout>
                                            <StackLayout Orientation="Horizontal" Spacing="5" Margin="12, 0, 0, 0" HorizontalOptions="StartAndExpand">

                                            </StackLayout>
                                            <StackLayout Orientation="Horizontal" Spacing="5" Margin="12, 3, 0, 0" HorizontalOptions="StartAndExpand">

                                            </StackLayout>
                                            <StackLayout Spacing="5" Margin="12, 3, 0, 0" Orientation="Horizontal" HorizontalOptions="StartAndExpand" VerticalOptions="Start">

                                            </StackLayout>
                                        </StackLayout>
                                        <StackLayout HorizontalOptions="EndAndExpand" VerticalOptions="Start" Margin="0, 25, 25, 0">
                                            <ImageButton HeightRequest="85" MinimumWidthRequest="85" x:Name="ButtonEditDocument" Source="baseline_more_vert_black_48.png" Clicked="ButtonEditDocument_OnClicked" Margin="0, 0, 15, 0" BackgroundColor="Transparent" WidthRequest="25" />
                                        </StackLayout>
                                    </StackLayout>
                                </Frame>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

Update 2 - Usage of Bindings

I worked out how I could use bindings to store the currently selected background of each viewcell in my model. At the moment I'm facing the issue that the UI doesn't update properly when the bound values have changed.
Here is the code I have written so far and how the page is updated when a different viewcell is tapped:

Document model class:

public class Document
{
        public bool HasDefaultColor { get; set; }

        public string CurrentlySelectedColorFromHex
        {
            get => ColorConverter.GetHexString(CurrentlySelectedColor);
        }

        [NotMapped]
        public Color CurrentlySelectedColor => HasDefaultColor ? DefaultColor : ActivatedColor;

        private static readonly Color DefaultColor = Color.WhiteSmoke;
        private static readonly Color ActivatedColor = Color.FromHex("#2E588C");
}

OnTapped function in code-behind:

        private void DocumentViewCell_OnTapped(object sender, EventArgs e)
        {
                    var documents = documentRepository.GetAll();
                    foreach (var document in documents)
                        document.HasDefaultColor = true;

                    selectedDocument.HasDefaultColor = false;
                    unitOfWork.Complete();
                    UpdatePage();
}

In UpdatePage() I want to refresh the listview properly after the bound collection has changed:

                viewModel.LoadDocuments();
                DocumentListView.BeginRefresh();

Sorry if this is a beginner question but I couldn't find an answer to this yet or couldn't figure out how to properly update the UI so that the background color of each viewcell is properly updated.
At least the bounded values are stored correctly at each OnTapped() call.

Update 3 - Added Converter

Hey guys, I have tried a few things and get stuck with updating the bound property of the model.
I have tried data triggers as well but couldn't change those data triggers correctly so they didn't worked as I expected them to do.

Until now I have added a custom bool to Color converter to convert the bound property:

    public class BoolToColorConverter : IValueConverter
    {
        private static readonly Color DefaultColor = Color.WhiteSmoke;
        private static readonly Color ActivatedColor = Color.FromHex("#2E588C");

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool activated)
                return activated ? ActivatedColor : DefaultColor;

            return DefaultColor;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is Color color)
            {
                if (color == DefaultColor)
                    return true;
            }

            return false;
        }

The Color converter returns the correct values, but I can't figure out how to update the model property at runtime in the OnTapped() method of each viewcell.

Currently this is my OnTapped() method:

        private void DocumentViewCell_OnTapped(object sender, EventArgs e)
        {
                // Determine which document was selected
                if (sender.GetType() == typeof(ViewCell))
                {
                    ViewCell selectedViewCell = (ViewCell)sender;

                    if (selectedViewCell.BindingContext != null && selectedViewCell.BindingContext.GetType() == typeof(Document))
                    {
                        Document document = (Document)selectedViewCell.BindingContext;

                        // Update backing field selectedDocument for correct bindings and to show correct detail page
                        if (document != null)
                            selectedDocument = document;
                    }
                }

Thanks for any help in advance and thanks to anyone who commented so far.

Body:
(See the answer which @Knoop gave for doing it in the right way with correct xamarin forms bindings and commands)

As I could accomplish my initial goal, which was to change the background color of each viewcell programmatically in code behind, I will post my result as an answer.

At first I learned that iterating over the viewcells is a bad idea because it's against the design pattern. So I used bindings, as well as a custom BoolToColor Converter to dynamically update the viewcells background color.

This is the code I have written:

Model class (Document):

   public class Document : BaseModel<int>, IDocument, INotifyPropertyChanged
    {
        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var changed = PropertyChanged;

            changed?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion // INotifyPropertyChanged

        public bool HasDefaultColor
        {
            get => hasDefaultColor;
            set
            {
                hasDefaultColor = value;
                OnPropertyChanged();
            }
        }
    }

The converter

public class BoolToColorConverter : IValueConverter (see question for detailed code...)

The implementation of the converter in xaml:

<Frame BackgroundColor="{Binding HasDefaultColor, Converter={converters:BoolToColorConverter}}"  Padding="0" HorizontalOptions="FillAndExpand" HasShadow="True">

And finally (which was the part where I got stuck with), properly updating the collection in the binded viewmodel in the OnTapped() method:

        private void DocumentViewCell_OnTapped(object sender, EventArgs e)
        {
            try
            {
                // Determine which document was selected
                if (sender.GetType() == typeof(ViewCell))
                {
                    ViewCell selectedViewCell = (ViewCell)sender;

                    if (selectedViewCell.BindingContext != null && selectedViewCell.BindingContext.GetType() == typeof(Document))
                    {
                        Document document = (Document)selectedViewCell.BindingContext;

                        if (document != null)
                        {
                            // Update default color (viewcell) for binded model
                            document.HasDefaultColor = !document.HasDefaultColor;

                            // Update backing field selectedDocument for correct bindings and to show correct detail page

                            ObservableCollection<Grouping<string, Document>> documents = viewModel.GroupedDocuments;
                            foreach (var group in documents)
                            {
                                foreach (var doc in group)
                                {
                                    if (doc.Name == document.Name)
                                    {
                                        doc.HasDefaultColor = document.HasDefaultColor;
                                    }
                                }
                            }

                            viewModel.GroupedDocuments = documents;
                            selectedDocument = document;
                        }
                    }
               }
           }
       }


来源: stackexchange

问:
Xamarin Forms: maintain selected tab over activity restarts
My main page uses a TabbedPage to group existing news into different lists. The tabs aren't fixed; they're built from a data binding operations against a collection that's retried through a web service call.

I'd like to persist the selected tab across activity restarts, but it seems like I'm missing something. Since there's no selected tab property (which can be set through data binding), I've tried to handle the PageChanged and the CurrentPageChangedCommand events. I'm using the PageChanged to set the selected tab to the previous selected tab and the CurrentPageChangedCommand is being used to update the persisted selected tab (I'm using the Application.Properties to make sure the selected tab survives app restarts).

Unfortunately, the events generated by the tab will always set tab 0 as the selected tab! Here's what I'm seeing (let's assume that my app was killed white tab 3 was active):

When data is bound to the TabbedPage.ItemsSource property, the tab will automatically fire the CurrentPageChangedCommand, passing the first tab (tab at position 0).

My code handles the event and updates the current persisted selected tab by changing the selected tab in the Properties dictionary. So now, instead of 3 (which was the value persisted when my app was killed), it will have 0.

Then the tab will fire the PagesChanged

When my code handles this event, it will try to update the selected tab. However, when it access the selected tab from the Properties dictionary, it will get the default tab (0) and not 3. This happens because the CurrentPageChangedCommand was fired before the PagesChanged event (step 2), completely overriding the previously persisted tab index.

This default behaviour will also give a bad user experience when the user refreshes the current list (pull to refresh) because he always ends up seeing tab 0 list.

So, any clues on how to solve this? How have you guys solved this?

Thanks.

答: Unfortunately, I had to abandon the MVVM approach...In the end, I had to resort to code and a couple of flags to control when the generated tab events should be handled. </p>

ContentLicense: CC BY-SA 4.0


问:
Why doesn't TypeScript catch that a const is being used before assignment?
I have a very simple example where TypeScript (3.5.1) is fine with the code, but it immediately throws an error when run.

I believe the issue here is that essentially value is declared but not initialized prior to getValue running.  This is pretty unintuitive imo but I understand this is how JS works.

However, why can't TS detect this issue in such a simple example?  Since value is a const, it seems to me TS should be able to determine exactly when it's set and predict that this code crashes.

console.log(getValue());

const value = "some string";

function getValue() {
  return value;
}
```

<p>In a second example without a function call, TS does catch that the variable is used before assignment:</p>

<pre class="lang-js prettyprint-override"><code>console.log(value);
const value = "some string";
</code>```

TSLint's no-use-before-declare also does not appear applicable.

Assuming TS/linting will not be able to catch this, is there a best practice to apply in the initial example that will avoid this crash?  "Always declare module-level consts at top of file" for example.

答:
I think the arrow function answer above answers your question the best, but just as a sidenote: deciding on a strict workflow will also prevent hoisting errors: declare vars, declare functions, call init function:</p>

```<code>const value = "some string"

function startApp() {
    console.log(getValue());
}

function getValue() {
    console.log("yo " + value)
    return value;
}

startApp()
</code>```

Body:
I have a very simple example where TypeScript (3.5.1) is fine with the code, but it immediately throws an error when run.

I believe the issue here is that essentially value is declared but not initialized prior to getValue running.  This is pretty unintuitive imo but I understand this is how JS works.

However, why can't TS detect this issue in such a simple example?  Since value is a const, it seems to me TS should be able to determine exactly when it's set and predict that this code crashes.

console.log(getValue());

const value = "some string";

function getValue() {
  return value;
}

In a second example without a function call, TS does catch that the variable is used before assignment:

console.log(value);
const value = "some string";

TSLint's no-use-before-declare also does not appear applicable.

Assuming TS/linting will not be able to catch this, is there a best practice to apply in the initial example that will avoid this crash?  "Always declare module-level consts at top of file" for example.

Body:
I think the arrow function answer above answers your question the best, but just as a sidenote: deciding on a strict workflow will also prevent hoisting errors: declare vars, declare functions, call init function:

const value = "some string"

function startApp() {
    console.log(getValue());
}

function getValue() {
    console.log("yo " + value)
    return value;
}

startApp()


问:
Cache server data globally and refresh views
I'm building an app that uses firebase for authentication and database functionality. Once a user signs up, a database record is stored for that user, containing some basic information like first name, last name etc.

Once a user logs in with his credentials I want to set a global variable (perhaps userDefaults?) which contains the user data for that specific user. Otherwise I have to fetch user data for every time I want to fill a label with for instance, a user's first name.

I managed to set userdefaults upon login and use this info in UIlables. But when I let users make changes to their data, of which some is important for the functioning of the app, I can update the server AND the userdefaults but the app itself doesn't update with the correct data. It keeps the old data in (for example) UIlables.

I would love to get some more insight on what the best work-flow is to manage situations like these.

When opening the app, i have a tabBarController set as rootviewcontroller. In the load of tabbarcontroller I have the following code retrieving the user data from firebase and saving it to userdefaults:

guard let uid = Auth.auth().currentUser?.uid else { return }
            Database.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
                print(snapshot.value ?? "")

              guard let dictionary = snapshot.value as? [String: Any] else { return }
                let firstname = dictionary["First name"] as? String
                let lastname = dictionary["Last name"] as? String

                print("first name is: " + firstname!)

                UserDefaults.standard.set(firstname, forKey: "userFirstName")

                print(UserDefaults.standard.value(forKey: "userFirstName"))

                self.setupViewControllers()

            }
```

<p>Then I continue on loading in all the viewcontrollers in the tabBarController:</p>

<pre class="lang-swift prettyprint-override"><code>self.setupViewControllers()
</code>```

During that process the labels in those viewcontrollers get filled in with the userdefaults data.

This is an example of a label being filled in with userDefaults but not being updated upon changing of userdefaults:

    let welcomeLabel: UILabel = {
        let label = UILabel()
        let attributedText = NSMutableAttributedString(string: "Welcome ")
        attributedText.append(NSAttributedString(string: "\(UserDefaults.standard.string(forKey: "userFirstName")!)"))
        label.attributedText = attributedText
        label.font = UIFont.systemFont(ofSize: 30, weight: .bold)
        return label
    }()
```

<p>this is a function i'm using to update the first name (via a textfield filled in by the user):</p>

<pre class="lang-swift prettyprint-override"><code>    @objc func updateName() {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        Database.database().reference().child("users").child(uid).updateChildValues(["First name" : updateNameField.text ?? ""])

        UserDefaults.standard.set(updateNameField.text, forKey: "userFirstName")

        print(UserDefaults.standard.value(forKey: "userFirstName"))
    }
</code>```

答:
So you'll have to organize things first. In a new file define constants such as below. These constant will be accessible in global scope unless private

Constants.swift

```<code>private let storedusername = "usname"
    private let storedName = "uname"
    private let displaypic = "udp"
    private let aboutme = "udesc"

    var myusername : String {
        get {
            return (UserDefaults.standard.string(forKey: storedusername)!)
        } set {
            UserDefaults.standard.set(newValue, forKey: storedusername)
        }
    }

    var myname : String {
        get {
            return (UserDefaults.standard.string(forKey: storedName)!)
        } set {
            UserDefaults.standard.set(newValue, forKey: storedName)
        }
    }

    var myProfileImage : Data {
        get {
            return (UserDefaults.standard.data(forKey: displaypic)!)
        } set {
            UserDefaults.standard.set(newValue, forKey: displaypic)
        }
    }

    var myAboutMe : String? {
        get {
            return (UserDefaults.standard.string(forKey: aboutme)!)
        } set {
            UserDefaults.standard.set(newValue, forKey: aboutme)
        }
    }
</code>```

Now the next time you want to save anything in UserDefaults, you'll just do the following anywhere throughout your code base :

```<code>myusername = "@CVEIjk"
</code>```

And to retrive it, just call it :

```<code>print(myusername)
</code>```

IMPORTANT NOTE --

Always remember to initialize them. You can do this as the user signs up. As soon as they fill out their details and hit submit, just save them to these variables. That wouldn't cause unnecessary crash.

You'll have to save them at every location you perform updates regarding these nodes in the database.

Now, the refreshing views part. I am taking a scenario where your ProfileView.swift has the view and user goes to EditProfile.swift for updating the content.

You initialize all your observers the place where the update will have the immediate effect. Because the view immediately after the update matters. The rest will be called through the getter of the aboutme

ProfileView.swift

```<code>func openEditView() {

        NotificationCenter.default.addObserver(self, selector: #selector(fetchUserDetails), name: Notification.Name("update"), object: nil)

        //setting this right before the segue will create an observer specifically and exclusively for updates. Hence you don't have to worry about the extra observers.

        perform(segue: With Identifier:)// Goes to the editProfile page
    }
</code>```

This function will be initially called in viewDidLoad(). At this time you need to make sure you have all the data, else it will produce no values. But if you are storing everything as the user signs up, you are safe.

```<code>@objc func fetchUserDetails() {
        if uid != nil {
            if myname.count > 0 { // This will check if the variable has anything in the memory or not. Dont confuse this with [Array].count
                self.nameLabel = myname
            }
        }
    }
</code>```

This function also acts an ab observer method. So when the notifications are posted they can run again.

Now, EditProfile.swift

In the block where you are updating the server, save the values and then create a Notification.post and put this method right before you dismiss(toViewController:)

```<code>   func updateUserCacheData(name: String, username: String, aboutme: String, ProfilePhoto: UIImage? = nil) {
        DispatchQueue.global().async {
            myname = name
            myusername = username
            myAboutMe = aboutme
            if self.newImage != nil {
                myProfileImage = self.newImage!.jpegData(compressionQuality: 1)!
            }
            DispatchQueue.main.async {
                NotificationCenter.default.post(name: .refreshProfileViews, object: nil)
            }
        }
    }

    func updateToServerAndBackToProfileView() {
        self.updateUserCacheData(name: iname!, username: iusername, aboutme: iaboutme!)
        self.dismiss(animated: true, completion: nil)
        }
    }
</code>```

As long as this goes back to ProfileView, your views will be instantly refreshed. You can keep an observer wherever you view will be first displayed after the dismiss. the rest will fetch updated content always. Also, don't forget to deinit your Observer in ProfileView

```<code>//This code is in ProfileView.swift
deinit {
        NotificationCenter.default.removeObserver(self, name: Notification.Name("update"), object: nil)
    }
</code>```

Also, in cases where the content might be empty, simply initialize it with empty content. For example, if user doesn't choose to add aboutme while signing up, you can just put

```<code>`myaboutme = ""`
</code>```

This will create a safe environment for you and you are well set.

Body:
I'm building an app that uses firebase for authentication and database functionality. Once a user signs up, a database record is stored for that user, containing some basic information like first name, last name etc.

Once a user logs in with his credentials I want to set a global variable (perhaps userDefaults?) which contains the user data for that specific user. Otherwise I have to fetch user data for every time I want to fill a label with for instance, a user's first name.

I managed to set userdefaults upon login and use this info in UIlables. But when I let users make changes to their data, of which some is important for the functioning of the app, I can update the server AND the userdefaults but the app itself doesn't update with the correct data. It keeps the old data in (for example) UIlables.

I would love to get some more insight on what the best work-flow is to manage situations like these.

When opening the app, i have a tabBarController set as rootviewcontroller. In the load of tabbarcontroller I have the following code retrieving the user data from firebase and saving it to userdefaults:

guard let uid = Auth.auth().currentUser?.uid else { return }
            Database.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
                print(snapshot.value ?? "")

              guard let dictionary = snapshot.value as? [String: Any] else { return }
                let firstname = dictionary["First name"] as? String
                let lastname = dictionary["Last name"] as? String

                print("first name is: " + firstname!)

                UserDefaults.standard.set(firstname, forKey: "userFirstName")

                print(UserDefaults.standard.value(forKey: "userFirstName"))

                self.setupViewControllers()

            }

Then I continue on loading in all the viewcontrollers in the tabBarController:

self.setupViewControllers()

During that process the labels in those viewcontrollers get filled in with the userdefaults data.

This is an example of a label being filled in with userDefaults but not being updated upon changing of userdefaults:

    let welcomeLabel: UILabel = {
        let label = UILabel()
        let attributedText = NSMutableAttributedString(string: "Welcome ")
        attributedText.append(NSAttributedString(string: "\(UserDefaults.standard.string(forKey: "userFirstName")!)"))
        label.attributedText = attributedText
        label.font = UIFont.systemFont(ofSize: 30, weight: .bold)
        return label
    }()

this is a function i'm using to update the first name (via a textfield filled in by the user):

    @objc func updateName() {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        Database.database().reference().child("users").child(uid).updateChildValues(["First name" : updateNameField.text ?? ""])

        UserDefaults.standard.set(updateNameField.text, forKey: "userFirstName")

        print(UserDefaults.standard.value(forKey: "userFirstName"))
    }

Body:
So you'll have to organize things first. In a new file define constants such as below. These constant will be accessible in global scope unless private

Constants.swift

private let storedusername = "usname"
    private let storedName = "uname"
    private let displaypic = "udp"
    private let aboutme = "udesc"

    var myusername : String {
        get {
            return (UserDefaults.standard.string(forKey: storedusername)!)
        } set {
            UserDefaults.standard.set(newValue, forKey: storedusername)
        }
    }

    var myname : String {
        get {
            return (UserDefaults.standard.string(forKey: storedName)!)
        } set {
            UserDefaults.standard.set(newValue, forKey: storedName)
        }
    }

    var myProfileImage : Data {
        get {
            return (UserDefaults.standard.data(forKey: displaypic)!)
        } set {
            UserDefaults.standard.set(newValue, forKey: displaypic)
        }
    }

    var myAboutMe : String? {
        get {
            return (UserDefaults.standard.string(forKey: aboutme)!)
        } set {
            UserDefaults.standard.set(newValue, forKey: aboutme)
        }
    }

Now the next time you want to save anything in UserDefaults, you'll just do the following anywhere throughout your code base :

myusername = "@CVEIjk"

And to retrive it, just call it :

print(myusername)

IMPORTANT NOTE --

Always remember to initialize them. You can do this as the user signs up. As soon as they fill out their details and hit submit, just save them to these variables. That wouldn't cause unnecessary crash.

You'll have to save them at every location you perform updates regarding these nodes in the database.

Now, the refreshing views part. I am taking a scenario where your ProfileView.swift has the view and user goes to EditProfile.swift for updating the content.

You initialize all your observers the place where the update will have the immediate effect. Because the view immediately after the update matters. The rest will be called through the getter of the aboutme

ProfileView.swift

func openEditView() {

        NotificationCenter.default.addObserver(self, selector: #selector(fetchUserDetails), name: Notification.Name("update"), object: nil)

        //setting this right before the segue will create an observer specifically and exclusively for updates. Hence you don't have to worry about the extra observers.

        perform(segue: With Identifier:)// Goes to the editProfile page
    }

This function will be initially called in viewDidLoad(). At this time you need to make sure you have all the data, else it will produce no values. But if you are storing everything as the user signs up, you are safe.

@objc func fetchUserDetails() {
        if uid != nil {
            if myname.count > 0 { // This will check if the variable has anything in the memory or not. Dont confuse this with [Array].count
                self.nameLabel = myname
            }
        }
    }

This function also acts an ab observer method. So when the notifications are posted they can run again.

Now, EditProfile.swift

In the block where you are updating the server, save the values and then create a Notification.post and put this method right before you dismiss(toViewController:)

   func updateUserCacheData(name: String, username: String, aboutme: String, ProfilePhoto: UIImage? = nil) {
        DispatchQueue.global().async {
            myname = name
            myusername = username
            myAboutMe = aboutme
            if self.newImage != nil {
                myProfileImage = self.newImage!.jpegData(compressionQuality: 1)!
            }
            DispatchQueue.main.async {
                NotificationCenter.default.post(name: .refreshProfileViews, object: nil)
            }
        }
    }

    func updateToServerAndBackToProfileView() {
        self.updateUserCacheData(name: iname!, username: iusername, aboutme: iaboutme!)
        self.dismiss(animated: true, completion: nil)
        }
    }

As long as this goes back to ProfileView, your views will be instantly refreshed. You can keep an observer wherever you view will be first displayed after the dismiss. the rest will fetch updated content always. Also, don't forget to deinit your Observer in ProfileView

//This code is in ProfileView.swift
deinit {
        NotificationCenter.default.removeObserver(self, name: Notification.Name("update"), object: nil)
    }

Also, in cases where the content might be empty, simply initialize it with empty content. For example, if user doesn't choose to add aboutme while signing up, you can just put

`myaboutme = ""`

This will create a safe environment for you and you are well set.


问:
Android - Pass data from link to app when installed and launched
I want to implement an app invitation, which I can share to users via a link

Hi, you've been invited to so and so. Click here to accept!
  http://myapp.com/?foo1=bar1&foo2=bar2

The link itself will redirect to the google play store, but I want to keep the foo1 = bar1, foo2 = bar2. And when the application has been launched, I want to get that data and do something with it.

Is this at all possible?

If there's not, is there another way that I could go about this?

Thanks!

答:
getting data from the download url

```<code>`https://play.google.com/store/apps/details?id=com.example.myapp&referrer=utm_content%3Dgroup232`
</code>```

after first install, get the referrer and its content (eg. get "group232")

Check here for more details
https://developer.android.com/google/play/installreferrer/library

Body:
getting data from the download url

`https://play.google.com/store/apps/details?id=com.example.myapp&referrer=utm_content%3Dgroup232`

after first install, get the referrer and its content (eg. get "group232")

Check here for more details
https://developer.android.com/google/play/installreferrer/library


问:
Creating 2 numbers from a one #C
I should create two new numbers from a one, the first group will contain digits which are divisible by 2 and the other group will contain the others.

```<code>int checkCount = 94321, num1 = 94321, count2 = 0, countRest = 0;

        while (checkCount > 0)
        {
            if (checkCount % 2 == 0)
                count2++;
            else
                countRest++;
            checkCount /= 10;
        }

        int[] a = new int[count2];
        int[] b = new int[countRest];

        int k2 = 0, kRest = 0;

        for (int j = 0; j < a.Length + b.Length; j++)
        {
            if (num1 % 2 == 0)
            {
                a[k2] = num1 % 10;
                k2++;
            }
            else
            {
                b[kRest] = num1 % 10;
                kRest++;
            }
            num1 /= 10;
        }
</code>```

I created two arrays with the numbers I should use, now how can I build two INT varabile when each one contains all of the numbers together from the array?

Example:
If I have this number - 12345 so
var = 24, other var = 135

If you have another solution without arrays I think it will be better.
Thank you.

答:
How can I build two INT varabile
  when each one contains all of the
  numbers together from the array?

I can't say for sure, but I think you're asking how to assemble a number given each of its digits in decreasing order of significance.

To 'append' a digit to a number, you can multiply the number by 10 and then add the digit to that. To create the 'assembled' number, you can perform this operation for each digit in the array,

```<code>int[] digits = ...
int num = digits.Aggregate(0, (numSoFar, digit) => 10 * numSoFar + digit);
</code>```

As a loop, this would look like:

```<code>int num = 0;

foreach(int digit in digits)
{
    num = 10 * num + digit;
}
</code>```

ContentLicense: CC BY-SA 3.0

Title: Creating 2 numbers from a one #C

Body:
I should create two new numbers from a one, the first group will contain digits which are divisible by 2 and the other group will contain the others.

int checkCount = 94321, num1 = 94321, count2 = 0, countRest = 0;

        while (checkCount > 0)
        {
            if (checkCount % 2 == 0)
                count2++;
            else
                countRest++;
            checkCount /= 10;
        }

        int[] a = new int[count2];
        int[] b = new int[countRest];

        int k2 = 0, kRest = 0;

        for (int j = 0; j < a.Length + b.Length; j++)
        {
            if (num1 % 2 == 0)
            {
                a[k2] = num1 % 10;
                k2++;
            }
            else
            {
                b[kRest] = num1 % 10;
                kRest++;
            }
            num1 /= 10;
        }

I created two arrays with the numbers I should use, now how can I build two INT varabile when each one contains all of the numbers together from the array?

Example:
If I have this number - 12345 so
var = 24, other var = 135

If you have another solution without arrays I think it will be better.
Thank you.

Body:
How can I build two INT varabile
  when each one contains all of the
  numbers together from the array?

I can't say for sure, but I think you're asking how to assemble a number given each of its digits in decreasing order of significance.

To 'append' a digit to a number, you can multiply the number by 10 and then add the digit to that. To create the 'assembled' number, you can perform this operation for each digit in the array,

int[] digits = ...
int num = digits.Aggregate(0, (numSoFar, digit) => 10 * numSoFar + digit);

As a loop, this would look like:

int num = 0;

foreach(int digit in digits)
{
    num = 10 * num + digit;
}


问:
Display name avatar (fallback) if Image not found using Canvas
How to display avatar taking letters from name like Google when actual image is not found.
 ========>

I would prefer a solution creating fallback image using canvas.

答:
this is for the image generator using javascript</p>

```<code>var colours = ["#1abc9c", "#2ecc71", "#3498db", "#9b59b6", "#34495e", "#16a085", "#27ae60", "#2980b9", "#8e44ad", "#2c3e50", "#f1c40f", "#e67e22", "#e74c3c", "#95a5a6", "#f39c12", "#d35400", "#c0392b", "#bdc3c7", "#7f8c8d"];

    var name = "Samundra Adhikari",
      nameSplit = name.split(" "),
      initials = nameSplit[0].charAt(0).toUpperCase() + nameSplit[1].charAt(0).toUpperCase();

    var charIndex = initials.charCodeAt(0) - 65,
      colourIndex = charIndex % 19;

    var canvas = document.createElement('canvas'); //es-lint disable
    canvas.width = '32';
    canvas.height = '32';
    var context = canvas.getContext("2d");
    context.fillStyle = colours[colourIndex];
    context.fillRect (0, 0, canvas.width, canvas.height);
    context.font = "16px Arial";
    context.textAlign = "center";
    context.fillStyle = "#FFF";
    context.fillText(initials,16,22);
    var dataUrl = canvas.toDataURL();
    return dataUrl;
</code>```

Body:
this is for the image generator using javascript

var colours = ["#1abc9c", "#2ecc71", "#3498db", "#9b59b6", "#34495e", "#16a085", "#27ae60", "#2980b9", "#8e44ad", "#2c3e50", "#f1c40f", "#e67e22", "#e74c3c", "#95a5a6", "#f39c12", "#d35400", "#c0392b", "#bdc3c7", "#7f8c8d"];

    var name = "Samundra Adhikari",
      nameSplit = name.split(" "),
      initials = nameSplit[0].charAt(0).toUpperCase() + nameSplit[1].charAt(0).toUpperCase();

    var charIndex = initials.charCodeAt(0) - 65,
      colourIndex = charIndex % 19;

    var canvas = document.createElement('canvas'); //es-lint disable
    canvas.width = '32';
    canvas.height = '32';
    var context = canvas.getContext("2d");
    context.fillStyle = colours[colourIndex];
    context.fillRect (0, 0, canvas.width, canvas.height);
    context.font = "16px Arial";
    context.textAlign = "center";
    context.fillStyle = "#FFF";
    context.fillText(initials,16,22);
    var dataUrl = canvas.toDataURL();
    return dataUrl;


问:
Check if a string has specific ending, erase this ending, then write those strings according to two other conditions
I've got a problem with preparing a readable report from my system.

I have to extract strings from "sil.catalog_no".

Firstly, I have to check if a string has ending like '-UW' and delete it.

After that, I have to extract that string (without -UW already), BUT without first part before first '-' or second '-' depending if before first '-' there is 'US'.

I know it's messed up, but I don't know how to describe it other way.

I have already tried SUBSTRING, LEFT, RIGHT and something with CHARINDEX, but my program/database/sql version(?) seems not to operate on those things and I can't find any other solution than these mentioned. Maybe it's because I don't use them correctly, I don't know.

The examples of strings contained in sil.catalog_no are:

```<code>HU-98010587
US-HU-88136FYT-719-UW
</code>```

So, in first example, I just have to check if there is '-UW' at the end. There isn't one, so I move to second step, and just remove 'HU-' and extract the rest which is '98010587'.

With the second one, I want to check and remove '-US' from the end. Then I want to erase whole 'US-HU-', because there is 'US' first and I want to get '88136FYT-719'.

EDIT:

After re-thinking the problem, I think I would like to know the way to erase specific parts of strings. Looking at image I've provided, I would like to erase all 'HU-', 'EMC-', 'US-', and '-UW' that appear in result.

答:
OK, I think the function regexp_replace can solve your problem. As below:

```<code>postgres=# select regexp_replace(regexp_replace('US-HU-88136FYT-719-UW','^([A-Z]+-)+',''),'(-[A-Z]+)+$','') as result;
    result
--------------
 88136FYT-719
(1 row)

postgres=# select regexp_replace(regexp_replace('HU-98010587','^([A-Z]+-)+',''),'(-[A-Z]+)+$','') as result;
  result
----------
 98010587
(1 row)

postgres=# select regexp_replace(regexp_replace('EMC-C13-PWR-7','^([A-Z]+-)+',''),'(-[A-Z]+)+$','') as result;
  result
-----------
 C13-PWR-7
</code>```

Or we remove the 'HU-', 'EMC-', 'US-', '-UW' more precisely, as below:

```<code>postgres=# select regexp_replace(regexp_replace('HU-98010587','^(HU-|EMC-|US-)+',''),'(-UW)+$','') as result;
  result
----------
 98010587
(1 row)

postgres=# select regexp_replace(regexp_replace('US-HU-88136FYT-719-UW','^(HU-|EMC-|US-)+',''),'(-UW)+$','') as result;
    result
--------------
 88136FYT-719
(1 row)

postgres=# select regexp_replace(regexp_replace('EMC-C13-PWR-7','^(HU-|EMC-|US-)+',''),'(-UW)+$','') as result;
  result
-----------
 C13-PWR-7
(1 row)

postgres=# select regexp_replace(regexp_replace('US-HU-88134UGQ-UW','^(HU-|EMC-|US-)+',''),'(-UW)+$','') as result;
  result
----------
 88134UGQ
</code>```

I think the two regular expressions above may get the right result both, and the second would accurately match your needs. Just try it.

Body:
I've got a problem with preparing a readable report from my system.

I have to extract strings from "sil.catalog_no".

Firstly, I have to check if a string has ending like '-UW' and delete it.

After that, I have to extract that string (without -UW already), BUT without first part before first '-' or second '-' depending if before first '-' there is 'US'.

I know it's messed up, but I don't know how to describe it other way.

I have already tried SUBSTRING, LEFT, RIGHT and something with CHARINDEX, but my program/database/sql version(?) seems not to operate on those things and I can't find any other solution than these mentioned. Maybe it's because I don't use them correctly, I don't know.

The examples of strings contained in sil.catalog_no are:

HU-98010587
US-HU-88136FYT-719-UW

So, in first example, I just have to check if there is '-UW' at the end. There isn't one, so I move to second step, and just remove 'HU-' and extract the rest which is '98010587'.

With the second one, I want to check and remove '-US' from the end. Then I want to erase whole 'US-HU-', because there is 'US' first and I want to get '88136FYT-719'.

EDIT:

After re-thinking the problem, I think I would like to know the way to erase specific parts of strings. Looking at image I've provided, I would like to erase all 'HU-', 'EMC-', 'US-', and '-UW' that appear in result.

Body:
OK, I think the function regexp_replace can solve your problem. As below:

postgres=# select regexp_replace(regexp_replace('US-HU-88136FYT-719-UW','^([A-Z]+-)+',''),'(-[A-Z]+)+$','') as result;
    result
--------------
 88136FYT-719
(1 row)

postgres=# select regexp_replace(regexp_replace('HU-98010587','^([A-Z]+-)+',''),'(-[A-Z]+)+$','') as result;
  result
----------
 98010587
(1 row)

postgres=# select regexp_replace(regexp_replace('EMC-C13-PWR-7','^([A-Z]+-)+',''),'(-[A-Z]+)+$','') as result;
  result
-----------
 C13-PWR-7

Or we remove the 'HU-', 'EMC-', 'US-', '-UW' more precisely, as below:

postgres=# select regexp_replace(regexp_replace('HU-98010587','^(HU-|EMC-|US-)+',''),'(-UW)+$','') as result;
  result
----------
 98010587
(1 row)

postgres=# select regexp_replace(regexp_replace('US-HU-88136FYT-719-UW','^(HU-|EMC-|US-)+',''),'(-UW)+$','') as result;
    result
--------------
 88136FYT-719
(1 row)

postgres=# select regexp_replace(regexp_replace('EMC-C13-PWR-7','^(HU-|EMC-|US-)+',''),'(-UW)+$','') as result;
  result
-----------
 C13-PWR-7
(1 row)

postgres=# select regexp_replace(regexp_replace('US-HU-88134UGQ-UW','^(HU-|EMC-|US-)+',''),'(-UW)+$','') as result;
  result
----------
 88134UGQ

I think the two regular expressions above may get the right result both, and the second would accurately match your needs. Just try it.


问:
React unable to find component
I'm trying to create a React App.. largely my attempts so far are based on the default application from create-react-app. Here's my App.js:

```<code>import React from 'react';
import './App.css';
import './Components/MyComponent';

function App() {
  return (
    <div className="App">
      <MyComponent/>
    </div>
  );
}

export default App;
</code>```

MyComponent is defined here:

```<code>import React from 'react';
import img from './Assets/img.png';
import imgComponent from './MyImage';

class MyComponent extends React.Component {
    render() {
      return
        <div>
            <imgComponent imageProp={img} />

        </div>
    }
}

export default MyComponent;
</code>```

When I run this, I get the error:

```<code>./src/App.js
  Line 8:  'MyComponent' is not defined  react/jsx-no-undef
</code>```

Please could someone tell me why I'm getting this error? I was under the impression that a combination of the import in App.js and the export default in MyComponent was all that was needed to use the component.

答:
In the App.js you added MyComponent to the render method, but MyComponent is not defined in your code (as the error message says).

Just change your third import:

import './Components/MyComponent';

To:

import MyComponent from './Components/MyComponent';

So you got the component you are using in your render function.

I hope it helps!

Title: React unable to find component

Body:
I'm trying to create a React App.. largely my attempts so far are based on the default application from create-react-app. Here's my App.js:

import React from 'react';
import './App.css';
import './Components/MyComponent';

function App() {
  return (

      <MyComponent/>

  );
}

export default App;

MyComponent is defined here:

import React from 'react';
import img from './Assets/img.png';
import imgComponent from './MyImage';

class MyComponent extends React.Component {
    render() {
      return

            <imgComponent imageProp={img} />

    }
}

export default MyComponent;

When I run this, I get the error:

./src/App.js
  Line 8:  'MyComponent' is not defined  react/jsx-no-undef

Please could someone tell me why I'm getting this error? I was under the impression that a combination of the import in App.js and the export default in MyComponent was all that was needed to use the component.


问:
Pass value to a private property
I have a couple of private properties defined like so..

```<code>private var tableConfig : TableViewConfig<Company, CompanyCell>?

private var tabledata = [Company]() {
    didSet {
      tableConfig?.items = tabledata
    }
  }
</code>```

Now there are 2 other properties defined like so...

```<code>  var model: Model?
  var companyCell: TableviewCell?
</code>```

Now, if get the value in model as Industry and the value in companyCell as IndustryCell, how can I update these values to private var tableConfig : TableViewConfig.... and private var tabledata = [Company]().... so that they will ultimately have the values like so..

```<code>private var tableConfig : TableViewConfig<Industry, IndustryCell>?

private var tabledata = [Industry]() {
    didSet {
      tableConfig?.items = tabledata
    }
  }
</code>```

答:
you can use a get set variabile to achieve this result

```<code>var _tabledata: [Industry] {
        get {
            return tabledata
        }
        set {
            tabledata = newValue
        }
    }
</code>```

Title: Pass value to a private property

Body:
I have a couple of private properties defined like so..

private var tableConfig : TableViewConfig<Company, CompanyCell>?

private var tabledata = [Company]() {
    didSet {
      tableConfig?.items = tabledata
    }
  }

Now there are 2 other properties defined like so...

  var model: Model?
  var companyCell: TableviewCell?

Now, if get the value in model as Industry and the value in companyCell as IndustryCell, how can I update these values to private var tableConfig : TableViewConfig.... and private var tabledata = [Company]().... so that they will ultimately have the values like so..

private var tableConfig : TableViewConfig<Industry, IndustryCell>?

private var tabledata = [Industry]() {
    didSet {
      tableConfig?.items = tabledata
    }
  }

Body:
you can use a get set variabile to achieve this result

var _tabledata: [Industry] {
        get {
            return tabledata
        }
        set {
            tabledata = newValue
        }
    }


问:
Filter elements of a JSON by their subelements' contents in Windows shell using JQ?
This may be asked elsewhere but I have trouble finding a similar case:

Trying to filter the Tor network's relay consensus (https://onionoo.torproject.org/details) based on whether a relay is "Running" and if it has a "Fast" flag or not in order to make another json made up of the selected relays. Possibly even a more concise version that only lists certain elements of each relay (nickname, fingerprint, etc).

I'm trying to use this in a batch script, which makes JQ difficult to work with as it requires hoops to jump through in order to make it work with Windows' shell.

Looking through the Tutorial and manual, I'm stumped. Anyone know of a solution?

答:
This filter will select relays with Running and Fast flags and yield an array of objects containing only nickname and fingerprint fields, tweak it to meet your requirements.

```<code>.relays | map(select(.flags | index("Running") and index("Fast")) | { nickname, fingerprint })
</code>```

Body:
This filter will select relays with Running and Fast flags and yield an array of objects containing only nickname and fingerprint fields, tweak it to meet your requirements.

.relays | map(select(.flags | index("Running") and index("Fast")) | { nickname, fingerprint })


问:
Simulate no network using Retrofit and MockWebServer
I want to simulate the no network case when using RetroFit and MockWebServer.

Im currently testing using Espresso and supplying the MockWebServers url to the RestAdapter before I start my tests. This works great for mocking server responses and so on but I cant see a simple way to script the java.net.ConnectException exception thrown when a device has no network. I can see the MockResponse allows throttling simulation and so on but not a custom exception.

I know I could go the root of mocking the actual web api interface used by retrofit but I would like to use the same approach as my other tests if possible by using MockWebServer.

I imagine I've just missed something simple :)

Thanks

答:
What worked for me is pointing the Retrofit URL (end-point) to a random non-existent host .
I used "thisIsARandomHost.com" and bingo i was able to mock the unknown host exception.

For example :  setAPP_URL = "http://thisIsARandomHost.com/";

Here , setAPP_URL is the string variable that contains my url which I pass on to retrofit , when I want to mock unknown host exception in my tests I set the url as above .For all other purposes it is set to the valid URL required by my app.

As stated in above answers , MockWebServer is a great library for mocking retrofit responses , but you don't need that library for mocking this exception . For mocking all other exceptions I would recommend MockWebServer , I use it a lot in my project for testing responses.

Note : You can set the app url to anything as long as that url doesn't exist on the web.


问:
ANTLR4: How to disable/enable skip of the whitespaces in the rule?
I have such grammar:

```<code>grammar SearchQuery;

queryDeclaration                        : predicateGroupItem predicateGroupItemWithBooleanOperator* ;
predicateGroupItemWithBooleanOperator   : groupOperator predicateGroupItem ;
predicateGroupItem                      : LEFT_BRACKET variable variableDelimiter
                                                expression expressionWithBoolean* RIGHT_BRACKET ;

variable                                : VARIABLE_STRING ;
variableDelimiter                       : VAR_DELIMITER  ;

expressionWithBoolean                   : boolOperator expression ;

expression                              : value ;

value                                   : polygonType;

boolOperator                            : or
                                        ;

or                                      : OR ;

groupOperator                           : AND ;

polygonType                             : POLYGON LEFT_BRACKET pointList (POLYGON_DELIMITER pointList)* RIGHT_BRACKET ;
longType                                : LONG ;
doubleType                              : DOUBLE ;

pointList                               : point
                                        | LEFT_BRACKET point ( POLYGON_DELIMITER point)* RIGHT_BRACKET
                                        ;

point                                   : latitude longitude ;

latitude                                : longType
                                        | doubleType
                                        ;

longitude                               : longType
                                        | doubleType
                                        ;

POLYGON                                 : [pP] [oO] [lL] [yY] [gG] [oO] [nN] ;

LONG                                    : DIGIT+ ;

DOUBLE                                  : DIGIT+ '.' DIGIT*
                                        | '.' DIGIT+
                                        ;

AND                                     : [aA] [nN] [dD] ;
OR                                      : COMMA
                                        | [oO] [rR]
                                        ;

VARIABLE_STRING                         : [a-zA-Z0-9.]+ ;
COMMA                                   : ',' ;
POLYGON_DELIMITER                       : ';' ;
VAR_DELIMITER                           : ':' ;

RIGHT_BRACKET                           : ')' ;
LEFT_BRACKET                            : '(' ;

WS                                      : [ \t\r\n]+ -> skip ;

fragment DIGIT                          : [0-9] ;
</code>```

Problem is that I need to disable global skip of the whitespaces in the point rule, because of when I will test such grammar with a value like this

```<code>(Location: POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10)))
</code>```

I will get the value of the polygonType in the visitor like this

```<code>POLYGON((3010,4040,2040,1020,3010))
</code>```

As you can see all points are without spaces...

Thanks for the future answer.

答:
As already commented by rici: the numbers are not glued together. If you invoke a toString() or getText() (or similar) on a parser context, it will simply return a string representation of itself. This string representation will not include spaces because those are skipped by the lexer.

The context will have separate tokens for the numbers. It will not have a token containing the input 3010, but will contain 2 tokens for it: 30 and 10.

Set a breakpoint in your visitor and see for yourself.

Body:
I have such grammar:

grammar SearchQuery;

queryDeclaration                        : predicateGroupItem predicateGroupItemWithBooleanOperator* ;
predicateGroupItemWithBooleanOperator   : groupOperator predicateGroupItem ;
predicateGroupItem                      : LEFT_BRACKET variable variableDelimiter
                                                expression expressionWithBoolean* RIGHT_BRACKET ;

variable                                : VARIABLE_STRING ;
variableDelimiter                       : VAR_DELIMITER  ;

expressionWithBoolean                   : boolOperator expression ;

expression                              : value ;

value                                   : polygonType;

boolOperator                            : or
                                        ;

or                                      : OR ;

groupOperator                           : AND ;

polygonType                             : POLYGON LEFT_BRACKET pointList (POLYGON_DELIMITER pointList)* RIGHT_BRACKET ;
longType                                : LONG ;
doubleType                              : DOUBLE ;

pointList                               : point
                                        | LEFT_BRACKET point ( POLYGON_DELIMITER point)* RIGHT_BRACKET
                                        ;

point                                   : latitude longitude ;

latitude                                : longType
                                        | doubleType
                                        ;

longitude                               : longType
                                        | doubleType
                                        ;

POLYGON                                 : [pP] [oO] [lL] [yY] [gG] [oO] [nN] ;

LONG                                    : DIGIT+ ;

DOUBLE                                  : DIGIT+ '.' DIGIT*
                                        | '.' DIGIT+
                                        ;

AND                                     : [aA] [nN] [dD] ;
OR                                      : COMMA
                                        | [oO] [rR]
                                        ;

VARIABLE_STRING                         : [a-zA-Z0-9.]+ ;
COMMA                                   : ',' ;
POLYGON_DELIMITER                       : ';' ;
VAR_DELIMITER                           : ':' ;

RIGHT_BRACKET                           : ')' ;
LEFT_BRACKET                            : '(' ;

WS                                      : [ \t\r\n]+ -> skip ;

fragment DIGIT                          : [0-9] ;

Problem is that I need to disable global skip of the whitespaces in the point rule, because of when I will test such grammar with a value like this

(Location: POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10)))

I will get the value of the polygonType in the visitor like this

POLYGON((3010,4040,2040,1020,3010))

As you can see all points are without spaces...

Thanks for the future answer.


问:
Changing the default landing page in ASP.NET Core Razor page?
I tried:

```<code>services.AddMvc().AddRazorPagesOptions(options =>
{
    options.Conventions.AddPageRoute("/Index", "old");
    options.Conventions.AddPageRoute("/NewIndex", "");
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
</code>```

This exception is thrown:

AmbiguousMatchException: The request matched multiple endpoints.
  Matches:

Page: /Index

Page: /NewIndex

I found this, that suggests renaming the Index page, but it obviously, if not a good reason presented, is a workaround. Can't I just change the default page without renaming the /Index page?

EDIT

The suggested SO threads don't cover the problem I explained, which is overriding the default route without having to rename the default Index page.
The accepted answer solved the problem.

答:
Default pages in Razor Pages are those that have an empty string route template generated for them. You can use a custom PageRouteModelConvention to remove the empty string route template that gets generated for the Index.cshtml page, and add it instead to whichever page you want as your default page:

```<code>public class HomePageRouteModelConvention : IPageRouteModelConvention
{
    public void Apply(PageRouteModel model)
    {
        if(model.RelativePath == "/Pages/Index.cshtml")
        {
            var currentHomePage = model.Selectors.Single(s => s.AttributeRouteModel.Template == string.Empty);
            model.Selectors.Remove(currentHomePage);
        }

        if (model.RelativePath == "/Pages/NewIndex.cshtml")
        {
            model.Selectors.Add(new SelectorModel()
            {
                AttributeRouteModel = new AttributeRouteModel
                {
                    Template = string.Empty
                }
            });
        }
    }
}
</code>```

You register the convention in ConfigureServices:

```<code>services.AddMvc().AddRazorPagesOptions(options =>
{
    options.Conventions.Add(new HomePageRouteModelConvention());
}).SetCompatibilityVersion(CompatibilityVersion.Latest);
</code>```

You can read more about custom page route model conventions here: https://www.learnrazorpages.com/advanced/custom-route-conventions

Body:
I tried:

services.AddMvc().AddRazorPagesOptions(options =>
{
    options.Conventions.AddPageRoute("/Index", "old");
    options.Conventions.AddPageRoute("/NewIndex", "");
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

This exception is thrown:

AmbiguousMatchException: The request matched multiple endpoints.
  Matches:

Page: /Index

Page: /NewIndex

I found this, that suggests renaming the Index page, but it obviously, if not a good reason presented, is a workaround. Can't I just change the default page without renaming the /Index page?

EDIT

The suggested SO threads don't cover the problem I explained, which is overriding the default route without having to rename the default Index page.
The accepted answer solved the problem.

Body:
Default pages in Razor Pages are those that have an empty string route template generated for them. You can use a custom PageRouteModelConvention to remove the empty string route template that gets generated for the Index.cshtml page, and add it instead to whichever page you want as your default page:

public class HomePageRouteModelConvention : IPageRouteModelConvention
{
    public void Apply(PageRouteModel model)
    {
        if(model.RelativePath == "/Pages/Index.cshtml")
        {
            var currentHomePage = model.Selectors.Single(s => s.AttributeRouteModel.Template == string.Empty);
            model.Selectors.Remove(currentHomePage);
        }

        if (model.RelativePath == "/Pages/NewIndex.cshtml")
        {
            model.Selectors.Add(new SelectorModel()
            {
                AttributeRouteModel = new AttributeRouteModel
                {
                    Template = string.Empty
                }
            });
        }
    }
}

You register the convention in ConfigureServices:

services.AddMvc().AddRazorPagesOptions(options =>
{
    options.Conventions.Add(new HomePageRouteModelConvention());
}).SetCompatibilityVersion(CompatibilityVersion.Latest);

You can read more about custom page route model conventions here: https://www.learnrazorpages.com/advanced/custom-route-conventions


问:
docker entrypoint running bash script gets "permission denied"
I'm trying to dockerize my node.js app. When the container is built I want it to run a git clone and then start the node server. Therefore I put these operations in a .sh script. And run the script as a single command in the ENTRYPOINT:

```<code>FROM ubuntu:14.04

RUN apt-get update && apt-get install -y build-essential libssl-dev gcc curl npm git

#install gcc 4.9
RUN apt-get install -y software-properties-common python-software-properties
RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test
RUN apt-get update
RUN apt-get install -y libstdc++-4.9-dev

#install newst nodejs
RUN curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
RUN apt-get install -y nodejs

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ADD package.json /usr/src/app/
RUN npm install

ADD docker-entrypoint.sh /usr/src/app/

EXPOSE 8080

ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"]
</code>```

My docker-entrypoint.sh looks like this:

```<code>git clone git@<repo>.git
git add remote upstream git@<upstream_repo>.git

/usr/bin/node server.js
</code>```

After building this image and run:

```<code>docker run --env NODE_ENV=development -p 8080:8080 -t -i <image>
</code>```

I'm getting:

```<code>docker: Error response from daemon: oci runtime error: exec: "/usr/src/app/docker-entrypoint.sh": permission denied.
</code>```

I shell into the container and the permission of docker-entrypoint.sh is:

```<code>-rw-r--r-- 1 root root 292 Aug 10 18:41 docker-entrypoint.sh
</code>```

three questions:

Does my bash script have wrong syntax?

How do I change the permission of a bash file before adding it into an image?

What's the best way to run multiple git commands in entrypoint without using a bash script?

Thanks.

答:
If you do not use DockerFile, you can simply add permission as command line argument of the bash:

```<code>docker run -t <image>  /bin/bash -c "chmod +x /usr/src/app/docker-entrypoint.sh; /usr/src/app/docker-entrypoint.sh"
</code>```

Body:
I'm trying to dockerize my node.js app. When the container is built I want it to run a git clone and then start the node server. Therefore I put these operations in a .sh script. And run the script as a single command in the ENTRYPOINT:

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y build-essential libssl-dev gcc curl npm git

#install gcc 4.9
RUN apt-get install -y software-properties-common python-software-properties
RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test
RUN apt-get update
RUN apt-get install -y libstdc++-4.9-dev

#install newst nodejs
RUN curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
RUN apt-get install -y nodejs

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ADD package.json /usr/src/app/
RUN npm install

ADD docker-entrypoint.sh /usr/src/app/

EXPOSE 8080

ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"]

My docker-entrypoint.sh looks like this:

git clone git@<repo>.git
git add remote upstream git@<upstream_repo>.git

/usr/bin/node server.js

After building this image and run:

docker run --env NODE_ENV=development -p 8080:8080 -t -i <image>

I'm getting:

docker: Error response from daemon: oci runtime error: exec: "/usr/src/app/docker-entrypoint.sh": permission denied.

I shell into the container and the permission of docker-entrypoint.sh is:

-rw-r--r-- 1 root root 292 Aug 10 18:41 docker-entrypoint.sh

three questions:

Does my bash script have wrong syntax?

How do I change the permission of a bash file before adding it into an image?

What's the best way to run multiple git commands in entrypoint without using a bash script?

Thanks.

Body:
If you do not use DockerFile, you can simply add permission as command line argument of the bash:

docker run -t <image>  /bin/bash -c "chmod +x /usr/src/app/docker-entrypoint.sh; /usr/src/app/docker-entrypoint.sh"


问:
How do I access layout_height from within my custom view?
I have a custom view and I simply wish to access the xml layout value of layout_height.

I am presently getting that information and storing it during onMeasure, but that only happens when the view is first painted. My view is an XY plot and it needs to know its height as early as possible so it can start performing calculations.

The view is on the fourth page of a viewFlipper layout, so the user may not flip to it for a while, but when they do flip to it, I would like the view to already contain data, which requires that I have the height to make the calculations.

Thanks!!!

答:
• Kotlin Version

The answers which are written to this question do not completely cover the issue. Actually, they are completing each other. To sum up the answer, first we should check the getAttributeValue returning value, then if the layout_height defined as dimension values, retrieve it using getDimensionPixelSize:

```<code>val layoutHeight = attrs?.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height")
var height = 0
when {
    layoutHeight.equals(ViewGroup.LayoutParams.MATCH_PARENT.toString()) ->
        height = ViewGroup.LayoutParams.MATCH_PARENT
    layoutHeight.equals(ViewGroup.LayoutParams.WRAP_CONTENT.toString()) ->
        height = ViewGroup.LayoutParams.WRAP_CONTENT
    else -> context.obtainStyledAttributes(attrs, intArrayOf(android.R.attr.layout_height)).apply {
        height = getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT)
        recycle()
    }
}

// Further to do something with `height`:
when (height) {
    ViewGroup.LayoutParams.MATCH_PARENT -> {
        // defined as `MATCH_PARENT`
    }
    ViewGroup.LayoutParams.WRAP_CONTENT -> {
        // defined as `WRAP_CONTENT`
    }
    in 0 until Int.MAX_VALUE -> {
        // defined as dimension values (here in pixels)
    }
}
</code>```

ContentLicense: CC BY-SA 2.5

Body:
• Kotlin Version

The answers which are written to this question do not completely cover the issue. Actually, they are completing each other. To sum up the answer, first we should check the getAttributeValue returning value, then if the layout_height defined as dimension values, retrieve it using getDimensionPixelSize:

val layoutHeight = attrs?.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height")
var height = 0
when {
    layoutHeight.equals(ViewGroup.LayoutParams.MATCH_PARENT.toString()) ->
        height = ViewGroup.LayoutParams.MATCH_PARENT
    layoutHeight.equals(ViewGroup.LayoutParams.WRAP_CONTENT.toString()) ->
        height = ViewGroup.LayoutParams.WRAP_CONTENT
    else -> context.obtainStyledAttributes(attrs, intArrayOf(android.R.attr.layout_height)).apply {
        height = getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT)
        recycle()
    }
}

// Further to do something with `height`:
when (height) {
    ViewGroup.LayoutParams.MATCH_PARENT -> {
        // defined as `MATCH_PARENT`
    }
    ViewGroup.LayoutParams.WRAP_CONTENT -> {
        // defined as `WRAP_CONTENT`
    }
    in 0 until Int.MAX_VALUE -> {
        // defined as dimension values (here in pixels)
    }
}


问:
how to make a unit test to assert if a property exist in a class or not using JUnit in java?
I have a class A{ private a;} that contain one property 'a', I want to know how to write a unit test using JUnit to test if really Class A has a property 'a'.

thanks

答:
A unit test is designed to assert the behavior of a component/class in terms of API : the application public interface or simply said the methods/fields exported/accessible from a client of the class' point of view.

Asserting about the structure of a component/class is a completely different concern.

Generally you don't want to do such a thing as it validates nothing in terms of API and it is still more the case for private fields that the client of the class have not to be aware of.

In your case you should rather focus on  public/protected methods that use the a field.


问:
Failed - network error when downloading excel file made by EPPlus.dll
I try to download an excel file made by EPPlus.dll from an asp.net c# web form application. but i get Failed - network error.
It should be noted that mentioned error just occurs in chrome and the job can be done successfully in another browsers.

by the way this error does not occure on my localhost and it happens only on the main server.

It would be very helpful if someone could explain solution for this problem.

http://www.irandnn.ir/blog/PostId/29/epplus

答:
I am exporting html table code which is in string variable HTML

Following Code Working For Me

```<code>byte[] myFile = Encoding.ASCII.GetBytes(HTML);
        Response.Clear();
        Response.Buffer = true;
        Response.AddHeader("Content-Type", "application/excel");
        Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0};", "BAGrowthReport.xls"));
        Response.AddHeader("content-length", myFile.Length.ToString()); //Here is the additional header which is required for Chrome.
        Response.BinaryWrite(myFile);
        Response.Flush();
        Response.Close();
</code>```

Body:
I am exporting html table code which is in string variable HTML

Following Code Working For Me

byte[] myFile = Encoding.ASCII.GetBytes(HTML);
        Response.Clear();
        Response.Buffer = true;
        Response.AddHeader("Content-Type", "application/excel");
        Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0};", "BAGrowthReport.xls"));
        Response.AddHeader("content-length", myFile.Length.ToString()); //Here is the additional header which is required for Chrome.
        Response.BinaryWrite(myFile);
        Response.Flush();
        Response.Close();


问:
How to explicitly invoke default method from a dynamic Proxy?
Since Java 8 interfaces could have default methods.
I know how to invoke the method explicitly from the implementing method, i.e.
(see Explicitly calling a default method in Java)

But how do I explicitly invoke the default method using reflection for example on a proxy?

Example:

```<code>interface ExampleMixin {

  String getText();

  default void printInfo(){
    System.out.println(getText());
  }
}

class Example {

  public static void main(String... args) throws Exception {

    Object target = new Object();

    Map<String, BiFunction<Object, Object[], Object>> behavior = new HashMap<>();

    ExampleMixin dynamic =
            (ExampleMixin) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class[]{ExampleMixin.class}, (Object proxy, Method method, Object[] arguments) -> {

                //custom mixin behavior
                if(behavior.containsKey(method.getName())) {
                    return behavior.get(method.getName()).apply(target, arguments);
                //default mixin behavior
                } else if (method.isDefault()) {
                    //this block throws java.lang.IllegalAccessException: no private access for invokespecial
                    return MethodHandles.lookup()
                                        .in(method.getDeclaringClass())
                                        .unreflectSpecial(method, method.getDeclaringClass())
                                        .bindTo(target)
                                        .invokeWithArguments();
                //no mixin behavior
                } else if (ExampleMixin.class == method.getDeclaringClass()) {
                    throw new UnsupportedOperationException(method.getName() + " is not supported");
                //base class behavior
                } else{
                    return method.invoke(target, arguments);
                }
            });

    //define behavior for abstract method getText()
    behavior.put("getText", (o, a) -> o.toString() + " myText");

    System.out.println(dynamic.getClass());
    System.out.println(dynamic.toString());
    System.out.println(dynamic.getText());

    //print info should by default implementation
    dynamic.printInfo();
  }
}
</code>```

Edit: I know a similar question has been asked in How do I invoke Java 8 default methods refletively, but this has not solved my problem for two reasons:

the problem described in that question aimed on how to invoked it via reflection in general - so no distinction between default and overriden method was made - and this is simple, you only need an instance.

one of the answers - using method handles - does only work with nasty hack (imho) like changing access modifiers to fields of the lookup class, which is the same category of "solutions" like this: Change private static final field using Java reflection: it's good to know it's possible, but I wouldn't use it in production - I'm looking for an "official" way to do it.

The IllegalAccessException is thrown in unreflectSpecial

```<code>Caused by: java.lang.IllegalAccessException: no private access for invokespecial: interface example.ExampleMixin, from example.ExampleMixin/package
at java.lang.invoke.MemberName.makeAccessException(MemberName.java:852)
at java.lang.invoke.MethodHandles$Lookup.checkSpecialCaller(MethodHandles.java:1568)
at java.lang.invoke.MethodHandles$Lookup.unreflectSpecial(MethodHandles.java:1227)
at example.Example.lambda$main$0(Example.java:30)
at example.Example$$Lambda$1/1342443276.invoke(Unknown Source)
</code>```

答:
We can see how spring process default method.

try invoke public method MethodHandles.privateLookupIn(Class,Lookup) first. This should success on jdk9+.

try create a Lookup with package private constructor MethodHandles.Lookup(Class).

fallback to MethodHandles.lookup().findSpecial(...)

https://github.com/spring-projects/spring-data-commons/blob/2.1.8.RELEASE/src/main/java/org/springframework/data/projection/DefaultMethodInvokingMethodInterceptor.java

Body:
Since Java 8 interfaces could have default methods.
I know how to invoke the method explicitly from the implementing method, i.e.
(see Explicitly calling a default method in Java)

But how do I explicitly invoke the default method using reflection for example on a proxy?

Example:

interface ExampleMixin {

  String getText();

  default void printInfo(){
    System.out.println(getText());
  }
}

class Example {

  public static void main(String... args) throws Exception {

    Object target = new Object();

    Map<String, BiFunction<Object, Object[], Object>> behavior = new HashMap<>();

    ExampleMixin dynamic =
            (ExampleMixin) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class[]{ExampleMixin.class}, (Object proxy, Method method, Object[] arguments) -> {

                //custom mixin behavior
                if(behavior.containsKey(method.getName())) {
                    return behavior.get(method.getName()).apply(target, arguments);
                //default mixin behavior
                } else if (method.isDefault()) {
                    //this block throws java.lang.IllegalAccessException: no private access for invokespecial
                    return MethodHandles.lookup()
                                        .in(method.getDeclaringClass())
                                        .unreflectSpecial(method, method.getDeclaringClass())
                                        .bindTo(target)
                                        .invokeWithArguments();
                //no mixin behavior
                } else if (ExampleMixin.class == method.getDeclaringClass()) {
                    throw new UnsupportedOperationException(method.getName() + " is not supported");
                //base class behavior
                } else{
                    return method.invoke(target, arguments);
                }
            });

    //define behavior for abstract method getText()
    behavior.put("getText", (o, a) -> o.toString() + " myText");

    System.out.println(dynamic.getClass());
    System.out.println(dynamic.toString());
    System.out.println(dynamic.getText());

    //print info should by default implementation
    dynamic.printInfo();
  }
}

Edit: I know a similar question has been asked in How do I invoke Java 8 default methods refletively, but this has not solved my problem for two reasons:

the problem described in that question aimed on how to invoked it via reflection in general - so no distinction between default and overriden method was made - and this is simple, you only need an instance.

one of the answers - using method handles - does only work with nasty hack (imho) like changing access modifiers to fields of the lookup class, which is the same category of "solutions" like this: Change private static final field using Java reflection: it's good to know it's possible, but I wouldn't use it in production - I'm looking for an "official" way to do it.

The IllegalAccessException is thrown in unreflectSpecial

Caused by: java.lang.IllegalAccessException: no private access for invokespecial: interface example.ExampleMixin, from example.ExampleMixin/package
at java.lang.invoke.MemberName.makeAccessException(MemberName.java:852)
at java.lang.invoke.MethodHandles$Lookup.checkSpecialCaller(MethodHandles.java:1568)
at java.lang.invoke.MethodHandles$Lookup.unreflectSpecial(MethodHandles.java:1227)
at example.Example.lambda$main$0(Example.java:30)
at example.Example$$Lambda$1/1342443276.invoke(Unknown Source)


问:
collect socket returned result in socket.io
In node.js (express.js) I can't do multiple return in an endpoint.

```<code>let result = {}
socket.on('receive_stream', ({data}) => {

  result = {
     ...result,
     ...data,
  }
  // must I send it here? res.send(result)
})
res.send(result) //this is empty object
</code>```

How can I wait and collect the stream to be finished, then only send the result to the client?

答:
Yes, in your case you must call req.send() in callback of socket.

But have many ways, the problem is about your code structure design pattern, you should read posts relevant to "callback promise async await in javascript"

Body:
In node.js (express.js) I can't do multiple return in an endpoint.

let result = {}
socket.on('receive_stream', ({data}) => {

  result = {
     ...result,
     ...data,
  }
  // must I send it here? res.send(result)
})
res.send(result) //this is empty object

How can I wait and collect the stream to be finished, then only send the result to the client?