问:
IllegalArgumentException: No view found for id for fragment --- ViewPager in ViewPager
I've met the problem that trouble me for days.

There is a ViewPager in the main activity which holds 3 Fragments as tab fragments. In the first fragment there is a ListView which holds some views, and which is the most important, another ViewPager. I want to hold some photos in the sub ViewPager, and use some more fragments here.

Now there is the trouble:

When the first Fragment is stopped (The third fragment in the parent ViewPager is seen on screen) and resumed (the user switch to the second fragment), the app crashes and the debugger says:

```<code>java.lang.IllegalArgumentException: No view found for id 0x7f05008b (com.example.viewpager:id/sub_viewpager) for fragment ScreenSlidePageFragment
</code>```

I've already use the getChildFragmentManager() as this is a situation of nested fragments.

Here is the key code of list adapter corresponding to the first fragment in the parent ViewPager:

```<code>@Override
public View getView(int position, View convertView, ViewGroup parent) {
    int type = getItemViewType(position);
    switch (type) {
        case TYPE_BANNER:
            if (convertView == null) {
                convertView = mBannerView.getBannerView(parent);
            }
            mBannerView.update(convertView);
            break;
        case TYPE_ITEM:
            break;
    }
    return convertView;
}
</code>```

Here is the code of mBannerView:

```<code>public class BannerView {

    private static final DisplayImageOptions IMAGE_OPTIONS_SCALE_STRETCHED =
            new DisplayImageOptions.Builder()
                    .cacheInMemory()
                    .cacheOnDisc()
                    .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
                    .build();

    private FragmentActivity mActivity;
    private Fragment mFragment;
    private List<Banner> mBanners;
    private ScreenSlidePagerAdapter mPagerAdapter;
    private ViewPager mViewPager;

    public BannerView(FragmentActivity activity, Fragment fragment) {
        mActivity = activity;
        mFragment = fragment;
    }

    public void update(View convertView) {
        mViewPager = (ViewPager) convertView;
        if (mBanners != null && !mBanners.isEmpty()) {
            if (mPagerAdapter == null) {
                mPagerAdapter = new ScreenSlidePagerAdapter(mFragment.getChildFragmentManager());
                mViewPager.setAdapter(mPagerAdapter);
            }
        }
        mViewPager.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnBannerClickListener != null) {
                    mOnBannerClickListener.onBannerClick();
                }
            }
        });
    }

    class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        public ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return new ScreenSlidePageFragment(mBanners.get(position).getImageUrl());
        }

        @Override
        public int getCount() {
            return mBanners == null ? 0 : mBanners.size();
        }
    }

    class ScreenSlidePageFragment extends Fragment {

        private String mUrl;

        ScreenSlidePageFragment(String url) {
            super();
            mUrl = url;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.item_banner, container, false);
            if (view != null) {
                ImageView imageView = (ImageView) view.findViewById(R.id.item_banner_image);
                imageView.setLayoutParams(new LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
                ImageLoader.getInstance().displayImage(mUrl, imageView, IMAGE_OPTIONS_SCALE_STRETCHED);
            }
            return view;
        }
    }
}
</code>```

Here is the detailed error list:

```<code>11-10 18:12:19.217    1444-1444/? E/MessageQueue-JNI﹕ java.lang.IllegalArgumentException: No view found for id 0x7f05008b (com.example.viewpager:id/sub_viewpager) for fragment ScreenSlidePageFragment{428d8ea0 #0 id=0x7f05008b}
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:919)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1884)
        at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1514)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
        at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1280)
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:672)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
        at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472)
        at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
        at android.support.v4.view.ViewPager$3.run(ViewPager.java:244)
        at android.support.v4.view.ViewPager.completeScroll(ViewPager.java:1761)
        at android.support.v4.view.ViewPager.onInterceptTouchEvent(ViewPager.java:1896)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1854)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1912)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1912)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1912)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2228)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1471)
        at android.app.Activity.dispatchTouchEvent(Activity.java:2424)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2176)
        at android.view.View.dispatchPointerEvent(View.java:7571)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3883)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3778)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3483)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3540)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5419)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5399)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5370)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5493)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:182)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:132)
        at android.os.Looper.loop(Looper.java:124)
        at android.app.ActivityThread.main(ActivityThread.java:5289)
        at java.lang
</code>```

答:
I got a similar problem.
In my situation, it is a RecyclerView that holds a ViewPager. Then, when the ViewPager is detached from RecyclerView and the container of the RecycleView first change its state to stop then change to resume. The FragmentManager of it will try to restore fragments it added. However at this time, the ViewPager is not attached to its parent. Thus FragmentManager throws a Exception.

Here is the source code:

```<code>ViewGroup container = null;
    if (f.mContainerId != 0) {
        if (f.mContainerId == -1) {
            this.throwException(new IllegalArgumentException("Cannot create fragment " + f + " for a container view with no id"));
        }

        container = (ViewGroup) this.mContainer.onFindViewById(f.mContainerId);
        if (container == null && !f.mRestored) {
            String resName;
            try {
                resName = f.getResources().getResourceName(f.mContainerId);
            } catch (NotFoundException var9) {
                resName = "unknown";
            }

            this.throwException(new IllegalArgumentException("No view found for id 0x" + Integer.toHexString(f.mContainerId) + " (" + resName + ") for fragment " + f));
        }
    }
</code>```

My solution is detach ViewPager's child Fragments when the ViewPager is detaching from RecycleView.

Here is an example:

```<code> @Override
public void postUnBindView(BaseCell cell) {
    super.postUnBindView(cell);
    if (vpFragmentManager != null && mPagerAdapter != null && mPagerAdapter.curFragments != null) {
        FragmentTransaction transaction = vpFragmentManager.beginTransaction();
        for (GuessLikePagerFragment guessLikePagerFragment : mPagerAdapter.curFragments.values()) {
            transaction.detach(guessLikePagerFragment);
        }
        transaction.commit();
    }
}
</code>```

Hope it helps.

Body:
I've met the problem that trouble me for days.

There is a ViewPager in the main activity which holds 3 Fragments as tab fragments. In the first fragment there is a ListView which holds some views, and which is the most important, another ViewPager. I want to hold some photos in the sub ViewPager, and use some more fragments here.

Now there is the trouble:

When the first Fragment is stopped (The third fragment in the parent ViewPager is seen on screen) and resumed (the user switch to the second fragment), the app crashes and the debugger says:

java.lang.IllegalArgumentException: No view found for id 0x7f05008b (com.example.viewpager:id/sub_viewpager) for fragment ScreenSlidePageFragment

I've already use the getChildFragmentManager() as this is a situation of nested fragments.

Here is the key code of list adapter corresponding to the first fragment in the parent ViewPager:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    int type = getItemViewType(position);
    switch (type) {
        case TYPE_BANNER:
            if (convertView == null) {
                convertView = mBannerView.getBannerView(parent);
            }
            mBannerView.update(convertView);
            break;
        case TYPE_ITEM:
            break;
    }
    return convertView;
}

Here is the code of mBannerView:

public class BannerView {

    private static final DisplayImageOptions IMAGE_OPTIONS_SCALE_STRETCHED =
            new DisplayImageOptions.Builder()
                    .cacheInMemory()
                    .cacheOnDisc()
                    .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
                    .build();

    private FragmentActivity mActivity;
    private Fragment mFragment;
    private List<Banner> mBanners;
    private ScreenSlidePagerAdapter mPagerAdapter;
    private ViewPager mViewPager;

    public BannerView(FragmentActivity activity, Fragment fragment) {
        mActivity = activity;
        mFragment = fragment;
    }

    public void update(View convertView) {
        mViewPager = (ViewPager) convertView;
        if (mBanners != null && !mBanners.isEmpty()) {
            if (mPagerAdapter == null) {
                mPagerAdapter = new ScreenSlidePagerAdapter(mFragment.getChildFragmentManager());
                mViewPager.setAdapter(mPagerAdapter);
            }
        }
        mViewPager.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnBannerClickListener != null) {
                    mOnBannerClickListener.onBannerClick();
                }
            }
        });
    }

    class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        public ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return new ScreenSlidePageFragment(mBanners.get(position).getImageUrl());
        }

        @Override
        public int getCount() {
            return mBanners == null ? 0 : mBanners.size();
        }
    }

    class ScreenSlidePageFragment extends Fragment {

        private String mUrl;

        ScreenSlidePageFragment(String url) {
            super();
            mUrl = url;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.item_banner, container, false);
            if (view != null) {
                ImageView imageView = (ImageView) view.findViewById(R.id.item_banner_image);
                imageView.setLayoutParams(new LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
                ImageLoader.getInstance().displayImage(mUrl, imageView, IMAGE_OPTIONS_SCALE_STRETCHED);
            }
            return view;
        }
    }
}

Here is the detailed error list:

11-10 18:12:19.217    1444-1444/? E/MessageQueue-JNI﹕ java.lang.IllegalArgumentException: No view found for id 0x7f05008b (com.example.viewpager:id/sub_viewpager) for fragment ScreenSlidePageFragment{428d8ea0 #0 id=0x7f05008b}
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:919)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1884)
        at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1514)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
        at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1280)
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:672)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
        at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472)
        at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
        at android.support.v4.view.ViewPager$3.run(ViewPager.java:244)
        at android.support.v4.view.ViewPager.completeScroll(ViewPager.java:1761)
        at android.support.v4.view.ViewPager.onInterceptTouchEvent(ViewPager.java:1896)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1854)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1912)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1912)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1912)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2228)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1471)
        at android.app.Activity.dispatchTouchEvent(Activity.java:2424)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2176)
        at android.view.View.dispatchPointerEvent(View.java:7571)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3883)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3778)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3483)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3540)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5419)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5399)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5370)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5493)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:182)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:132)
        at android.os.Looper.loop(Looper.java:124)
        at android.app.ActivityThread.main(ActivityThread.java:5289)
        at java.lang

Body:
I got a similar problem.
In my situation, it is a RecyclerView that holds a ViewPager. Then, when the ViewPager is detached from RecyclerView and the container of the RecycleView first change its state to stop then change to resume. The FragmentManager of it will try to restore fragments it added. However at this time, the ViewPager is not attached to its parent. Thus FragmentManager throws a Exception.

Here is the source code:

ViewGroup container = null;
    if (f.mContainerId != 0) {
        if (f.mContainerId == -1) {
            this.throwException(new IllegalArgumentException("Cannot create fragment " + f + " for a container view with no id"));
        }

        container = (ViewGroup) this.mContainer.onFindViewById(f.mContainerId);
        if (container == null && !f.mRestored) {
            String resName;
            try {
                resName = f.getResources().getResourceName(f.mContainerId);
            } catch (NotFoundException var9) {
                resName = "unknown";
            }

            this.throwException(new IllegalArgumentException("No view found for id 0x" + Integer.toHexString(f.mContainerId) + " (" + resName + ") for fragment " + f));
        }
    }

My solution is detach ViewPager's child Fragments when the ViewPager is detaching from RecycleView.

Here is an example:

 @Override
public void postUnBindView(BaseCell cell) {
    super.postUnBindView(cell);
    if (vpFragmentManager != null && mPagerAdapter != null && mPagerAdapter.curFragments != null) {
        FragmentTransaction transaction = vpFragmentManager.beginTransaction();
        for (GuessLikePagerFragment guessLikePagerFragment : mPagerAdapter.curFragments.values()) {
            transaction.detach(guessLikePagerFragment);
        }
        transaction.commit();
    }
}

Hope it helps.


来源: stackexchange

问:
How to execute a Bash command only if a Docker container with a given name does not exist?
On a Jenkins machine I would like to create a docker container with a specified name only if it does not already exist (in a shell script). I thought I might run the command to create the container regardless and ignore the failure if there was one, but this causes my jenkins job to fail.

Hence, I would like to know how I can check if a docker container exists or not using bash.

答:
Piggy-backing off of @Fernando César.

This checks for the container id from the given container name and suppresses error output ( 2> /dev/null ).

CONTAINER_NAME="awesome-container"

CONTAINER_ID=$(docker inspect --format="{{.Id}}" ${CONTAINER_NAME} 2> /dev/null)
if [[ "${CONTAINER_ID}" ]]; then
  # container found.
else
  # container not found.
fi
```

ContentLicense: CC BY-SA 4.0


问:
Configuring Ant Design with Angular 8 and SCSS
Does anyone have experience setting up Ant Design in an Angular project with SCSS styles? Setting up is not the difficult part but I'm trying to override the variables that Ant Design exposes in their design system. The problem is that they use .less files for their styling and I'm not sure how to use that in unison with scss.

I have seen some examples for React projects. But angular creates some other issues because it processes the scss files itself and I'm not sure how to get around it.

I created the project using Angular CLI.

Here's some of the code:

angular.json  file

```<code>{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "ant-design-poc": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./src/custom-webpack-2.config.js"
            },
            "outputPath": "dist/ant-design-poc",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss",
              "node_modules/ng-zorro-antd/ng-zorro-antd.less"
            ],
            "scripts": [],
            "es5BrowserSupport": true
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-builders/custom-webpack:dev-server",
          "options": {
            "customWebpackConfig": {
              "path": "./src/custom-webpack-2.config.js"
            },
            "browserTarget": "ant-design-poc:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "ant-design-poc:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "ant-design-poc:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "karmaConfig": "src/karma.conf.js",
            "styles": [
              "src/styles.scss"
            ],
            "scripts": [],
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "src/tsconfig.app.json",
              "src/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    },
    "ant-design-poc-e2e": {
      "root": "e2e/",
      "projectType": "application",
      "prefix": "",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "ant-design-poc:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "ant-design-poc:serve:production"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": "e2e/tsconfig.e2e.json",
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    }
  },
  "defaultProject": "ant-design-poc",
  "schematics": {
    "@schematics/angular:component": {
      "styleext": "scss"
    }
  }
}
</code>```

Webpack configuration

```<code>const path = require('path');

const AntdScssThemePlugin = require('antd-scss-theme-plugin');

const config = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader'
          },
          AntdScssThemePlugin.themify({
            loader: 'sass-loader',
          }),
        ],
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader'
          },
          AntdScssThemePlugin.themify('less-loader'),
        ],
      },
    ],
  },
  watchOptions: {
    ignored: /dist/,
  },
};

module.exports = config;

</code>```

Styles.scss file

```<code>@import "../node_modules/ng-zorro-antd/ng-zorro-antd.less"; //import ant design style file

$primary-color: #0077ff;

</code>```

package.json

```<code>{
  "name": "ant-design-poc",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~8.2.14",
    "@angular/common": "~8.2.14",
    "@angular/compiler": "~8.2.14",
    "@angular/core": "~8.2.14",
    "@angular/forms": "~8.2.14",
    "@angular/platform-browser": "~8.2.14",
    "@angular/platform-browser-dynamic": "~8.2.14",
    "@angular/router": "~8.2.14",
    "core-js": "^2.5.4",
    "ng-zorro-antd": "^7.5.1",
    "rxjs": "~6.5.3",
    "tslib": "^1.9.0",
    "zone.js": "~0.9.1"
  },
  "devDependencies": {
    "@angular-builders/custom-webpack": "^8.4.1",
    "@angular-devkit/build-angular": "^0.803.20",
    "@angular/cli": "~8.3.20",
    "@angular/compiler-cli": "~8.2.14",
    "@angular/language-service": "~8.2.14",
    "@types/jasmine": "~2.8.8",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "~8.9.4",
    "antd-scss-theme-plugin": "^1.0.8",
    "babel-loader": "^8.0.6",
    "codelyzer": "^5.0.1",
    "css-loader": "^3.2.1",
    "jasmine-core": "~2.99.1",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~1.1.2",
    "karma-jasmine-html-reporter": "^0.2.2",
    "less-loader": "^5.0.0",
    "node-sass": "^4.13.0",
    "protractor": "~5.4.0",
    "sass": "^1.23.7",
    "sass-loader": "^7.0.1",
    "style-loader": "^1.0.1",
    "ts-node": "~7.0.0",
    "tslint": "~5.11.0",
    "typescript": "~3.5.3"
  }
}
</code>```

This is the error that I get when I try to build the project:

```<code>ERROR in ./node_modules/ng-zorro-antd/ng-zorro-antd.less (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/less-loader/dist/cjs.js??ref--16-3!./node_modules/style-loader/dist!./node_modules/css-loader/dist/cjs.js??ref--20-1!./node_modules/antd-scss-theme-plugin/build/dist/lib/antdLessLoader.js??ref--20-2!./node_modules/ng-zorro-antd/ng-zorro-antd.less)
Module build failed (from ./node_modules/less-loader/dist/cjs.js):

var content = require("!!../css-loader/dist/cjs.js??ref--20-1!../antd-scss-theme-plugin/build/dist/lib/antdLessLoader.js??ref--20-2!./ng-zorro-antd.less");
          ^
Unrecognised input
      in /Users/shotbyms/Work/Zenhomes-Experiments/ng-ant-design-poc/ant-design-poc/node_modules/ng-zorro-antd/ng-zorro-antd.less (line 1, column 12)
ERROR in ./src/styles.scss (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/sass-loader/lib/loader.js??ref--15-3!./node_modules/style-loader/dist!./node_modules/css-loader/dist/cjs.js!./node_modules/antd-scss-theme-plugin/build/dist/lib/antdSassLoader.js??ref--19-2!./src/styles.scss)
Module build failed (from ./node_modules/sass-loader/lib/loader.js):

@import "../node_modules/ng-zorro-antd/ng-zorro-antd.less"; //import ant design style file
^
      Invalid CSS after "v": expected 1 selector or at-rule, was "var content = requi"
      in /Users/shotbyms/Work/Zenhomes-Experiments/ng-ant-design-poc/ant-design-poc/src/styles.scss (line 1, column 1)
</code>```

Does anyone have any experience with this? How can I use the theme and use scss with it at the same time?

Appreciate all the help, thank you in advance :)

答:
This mehthod worked for me
 can check the documentaion here.

https://ng.ant.design/docs/customize-theme/en

Without schematics#

Create a standalone less file named theme.less in src folder, and add the path of it to the list of styles in angular.json file.

...
  "styles": [
    ...
    "src/theme.less"
    ...
  ]
...
Here is an example of theme.less

The base color is changed to #f5222d in the example below.

// -------- import official less file -----------
@import "../node_modules/ng-zorro-antd/ng-zorro-antd.less";

// -------- override less var -----------
@primary-color          : #f5222d;

Body:
Does anyone have experience setting up Ant Design in an Angular project with SCSS styles? Setting up is not the difficult part but I'm trying to override the variables that Ant Design exposes in their design system. The problem is that they use .less files for their styling and I'm not sure how to use that in unison with scss.

I have seen some examples for React projects. But angular creates some other issues because it processes the scss files itself and I'm not sure how to get around it.

I created the project using Angular CLI.

Here's some of the code:

angular.json  file

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "ant-design-poc": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./src/custom-webpack-2.config.js"
            },
            "outputPath": "dist/ant-design-poc",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss",
              "node_modules/ng-zorro-antd/ng-zorro-antd.less"
            ],
            "scripts": [],
            "es5BrowserSupport": true
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-builders/custom-webpack:dev-server",
          "options": {
            "customWebpackConfig": {
              "path": "./src/custom-webpack-2.config.js"
            },
            "browserTarget": "ant-design-poc:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "ant-design-poc:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "ant-design-poc:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "karmaConfig": "src/karma.conf.js",
            "styles": [
              "src/styles.scss"
            ],
            "scripts": [],
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "src/tsconfig.app.json",
              "src/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    },
    "ant-design-poc-e2e": {
      "root": "e2e/",
      "projectType": "application",
      "prefix": "",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "ant-design-poc:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "ant-design-poc:serve:production"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": "e2e/tsconfig.e2e.json",
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    }
  },
  "defaultProject": "ant-design-poc",
  "schematics": {
    "@schematics/angular:component": {
      "styleext": "scss"
    }
  }
}

Webpack configuration

const path = require('path');

const AntdScssThemePlugin = require('antd-scss-theme-plugin');

const config = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader'
          },
          AntdScssThemePlugin.themify({
            loader: 'sass-loader',
          }),
        ],
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader'
          },
          AntdScssThemePlugin.themify('less-loader'),
        ],
      },
    ],
  },
  watchOptions: {
    ignored: /dist/,
  },
};

module.exports = config;

Styles.scss file

@import "../node_modules/ng-zorro-antd/ng-zorro-antd.less"; //import ant design style file

$primary-color: #0077ff;

package.json

{
  "name": "ant-design-poc",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~8.2.14",
    "@angular/common": "~8.2.14",
    "@angular/compiler": "~8.2.14",
    "@angular/core": "~8.2.14",
    "@angular/forms": "~8.2.14",
    "@angular/platform-browser": "~8.2.14",
    "@angular/platform-browser-dynamic": "~8.2.14",
    "@angular/router": "~8.2.14",
    "core-js": "^2.5.4",
    "ng-zorro-antd": "^7.5.1",
    "rxjs": "~6.5.3",
    "tslib": "^1.9.0",
    "zone.js": "~0.9.1"
  },
  "devDependencies": {
    "@angular-builders/custom-webpack": "^8.4.1",
    "@angular-devkit/build-angular": "^0.803.20",
    "@angular/cli": "~8.3.20",
    "@angular/compiler-cli": "~8.2.14",
    "@angular/language-service": "~8.2.14",
    "@types/jasmine": "~2.8.8",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "~8.9.4",
    "antd-scss-theme-plugin": "^1.0.8",
    "babel-loader": "^8.0.6",
    "codelyzer": "^5.0.1",
    "css-loader": "^3.2.1",
    "jasmine-core": "~2.99.1",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~1.1.2",
    "karma-jasmine-html-reporter": "^0.2.2",
    "less-loader": "^5.0.0",
    "node-sass": "^4.13.0",
    "protractor": "~5.4.0",
    "sass": "^1.23.7",
    "sass-loader": "^7.0.1",
    "style-loader": "^1.0.1",
    "ts-node": "~7.0.0",
    "tslint": "~5.11.0",
    "typescript": "~3.5.3"
  }
}

This is the error that I get when I try to build the project:

ERROR in ./node_modules/ng-zorro-antd/ng-zorro-antd.less (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/less-loader/dist/cjs.js??ref--16-3!./node_modules/style-loader/dist!./node_modules/css-loader/dist/cjs.js??ref--20-1!./node_modules/antd-scss-theme-plugin/build/dist/lib/antdLessLoader.js??ref--20-2!./node_modules/ng-zorro-antd/ng-zorro-antd.less)
Module build failed (from ./node_modules/less-loader/dist/cjs.js):

var content = require("!!../css-loader/dist/cjs.js??ref--20-1!../antd-scss-theme-plugin/build/dist/lib/antdLessLoader.js??ref--20-2!./ng-zorro-antd.less");
          ^
Unrecognised input
      in /Users/shotbyms/Work/Zenhomes-Experiments/ng-ant-design-poc/ant-design-poc/node_modules/ng-zorro-antd/ng-zorro-antd.less (line 1, column 12)
ERROR in ./src/styles.scss (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/sass-loader/lib/loader.js??ref--15-3!./node_modules/style-loader/dist!./node_modules/css-loader/dist/cjs.js!./node_modules/antd-scss-theme-plugin/build/dist/lib/antdSassLoader.js??ref--19-2!./src/styles.scss)
Module build failed (from ./node_modules/sass-loader/lib/loader.js):

@import "../node_modules/ng-zorro-antd/ng-zorro-antd.less"; //import ant design style file
^
      Invalid CSS after "v": expected 1 selector or at-rule, was "var content = requi"
      in /Users/shotbyms/Work/Zenhomes-Experiments/ng-ant-design-poc/ant-design-poc/src/styles.scss (line 1, column 1)

Does anyone have any experience with this? How can I use the theme and use scss with it at the same time?

Appreciate all the help, thank you in advance :)


问:
How to delete variables and return a new statistical model in UI?
I am creating a appshiny to analyze a statistical model. In it, the user places the data set and a logistic regression model is returned. I would like non-significant variables to be excluded so that I can analyze a new model. What would be my mistake in this app?
 Any help or direction would be appreciated. Thanks

```<code>     library(shiny)

        ui <- fluidPage(

          titlePanel("-"),

          sidebarLayout(

            sidebarPanel(

              fileInput(inputId="arquivo", "Selecione o arquivo",accept = ".csv"),

              selectInput(inputId = "insi", "Selecione as variaveis não significativas", choices = "" ,multiple = TRUE ),

              actionButton(inputId = "acao", label = "Refaça o modelo")

            ),

            mainPanel(
              tabsetPanel(type = "tab",
                          tabPanel("Dados",tableOutput("dados")),
                          tabPanel("Ajuste", verbatimTextOutput("model"))
              )
            )
          )
        )

        server <- function(input, output, session) {

          k <- reactive({
            if(is.null(input$arquivo))     return(NULL)
            k <- read.csv(input$arquivo$datapath, header = TRUE, stringsAsFactors = FALSE)

            updateSelectInput(session = session, inputId = "insi", choices = names(k))
            return(k)
          })

           output$dados <- renderTable({
           k <- req(k())
           return(k)
           })

          output$model <- renderPrint({
            k <- req(k())

            v <- ncol(k)

            y <- k[, 1]
            x <- k[, -1]

            mData <- data.frame(vY = y, mX = x)
            colnames(mData) <- c("vY", paste("VX", 2:v, sep = ""))

            mod <- glm(vY ~ ., data = mData, family = binomial)

            print(summary(mod))

            if (input$acao == TRUE){

              v <- ncol(k)
              y <- k[, 1]
              x <- k[, -1]

              insi <- input$insi
              x <- x[ , - (insi)]

              mData <- data.frame(vY = y, mX = x)
              colnames(mData) <- c("vY", paste("VX", 2:v, sep = ""))

              mod <- glm(vY ~ ., data = mData, family = binomial)

              print(summary(mod))
            }

          })

        }

        shinyApp(ui = ui, server = server)
</code>```

答:
You're excluding columns by name, but earlier you renamed all the predictor columns as VX2, VX3, etc.  You need to preserve the original column names so you know which ones to exclude.

Also, in the code, you store the number of predictor columns as v; this needs to happen after the user-selected columns have been removed.  Otherwise, the count will be wrong.

This should do the trick:

```<code>output$model <- renderPrint({
  k <- req(k())

  v <- ncol(k)

  y <- k[, 1]
  x <- k[, -1]

  mData <- data.frame(vY = y, mX = x)
  real.cols = colnames(x)
  colnames(mData) <- c("vY", paste("VX", 2:v, sep = ""))

  mod <- glm(vY ~ ., data = mData, family = binomial)

  print(summary(mod))

  if (input$acao == TRUE){

    y <- k[, 1]
    x <- k[, -1]

    insi <- input$insi
    x <- data.frame(x[ , -which(real.cols %in% insi)])

    v <- ncol(x)

    mData <- data.frame(vY = y, mX = x)
    colnames(mData) <- c("vY", paste("VX", 2:(v+1), sep = ""))

    mod <- glm(vY ~ ., data = mData, family = binomial)

    print(summary(mod))
  }

})
</code>```

Body:
I am creating a appshiny to analyze a statistical model. In it, the user places the data set and a logistic regression model is returned. I would like non-significant variables to be excluded so that I can analyze a new model. What would be my mistake in this app?
 Any help or direction would be appreciated. Thanks

     library(shiny)

        ui <- fluidPage(

          titlePanel("-"),

          sidebarLayout(

            sidebarPanel(

              fileInput(inputId="arquivo", "Selecione o arquivo",accept = ".csv"),

              selectInput(inputId = "insi", "Selecione as variaveis não significativas", choices = "" ,multiple = TRUE ),

              actionButton(inputId = "acao", label = "Refaça o modelo")

            ),

            mainPanel(
              tabsetPanel(type = "tab",
                          tabPanel("Dados",tableOutput("dados")),
                          tabPanel("Ajuste", verbatimTextOutput("model"))
              )
            )
          )
        )

        server <- function(input, output, session) {

          k <- reactive({
            if(is.null(input$arquivo))     return(NULL)
            k <- read.csv(input$arquivo$datapath, header = TRUE, stringsAsFactors = FALSE)

            updateSelectInput(session = session, inputId = "insi", choices = names(k))
            return(k)
          })

           output$dados <- renderTable({
           k <- req(k())
           return(k)
           })

          output$model <- renderPrint({
            k <- req(k())

            v <- ncol(k)

            y <- k[, 1]
            x <- k[, -1]

            mData <- data.frame(vY = y, mX = x)
            colnames(mData) <- c("vY", paste("VX", 2:v, sep = ""))

            mod <- glm(vY ~ ., data = mData, family = binomial)

            print(summary(mod))

            if (input$acao == TRUE){

              v <- ncol(k)
              y <- k[, 1]
              x <- k[, -1]

              insi <- input$insi
              x <- x[ , - (insi)]

              mData <- data.frame(vY = y, mX = x)
              colnames(mData) <- c("vY", paste("VX", 2:v, sep = ""))

              mod <- glm(vY ~ ., data = mData, family = binomial)

              print(summary(mod))
            }

          })

        }

        shinyApp(ui = ui, server = server)

Body:
You're excluding columns by name, but earlier you renamed all the predictor columns as VX2, VX3, etc.  You need to preserve the original column names so you know which ones to exclude.

Also, in the code, you store the number of predictor columns as v; this needs to happen after the user-selected columns have been removed.  Otherwise, the count will be wrong.

This should do the trick:

output$model <- renderPrint({
  k <- req(k())

  v <- ncol(k)

  y <- k[, 1]
  x <- k[, -1]

  mData <- data.frame(vY = y, mX = x)
  real.cols = colnames(x)
  colnames(mData) <- c("vY", paste("VX", 2:v, sep = ""))

  mod <- glm(vY ~ ., data = mData, family = binomial)

  print(summary(mod))

  if (input$acao == TRUE){

    y <- k[, 1]
    x <- k[, -1]

    insi <- input$insi
    x <- data.frame(x[ , -which(real.cols %in% insi)])

    v <- ncol(x)

    mData <- data.frame(vY = y, mX = x)
    colnames(mData) <- c("vY", paste("VX", 2:(v+1), sep = ""))

    mod <- glm(vY ~ ., data = mData, family = binomial)

    print(summary(mod))
  }

})


问:
ggplot - x-axis shows data beyond specified range for longer time periods
Here's some sample data for a company's Net revenue split by two cohorts:

```<code>data <- data.frame(dates = rep(seq(as.Date("2000/1/1"), by = "month", length.out = 48), each = 2),
                   revenue = rep(seq(10000, by = 1000, length.out = 48), each = 2) * rnorm(96, mean = 1, sd = 0.1),
                   cohort = c("Group 1", "Group 2"))
</code>```

I can show one year's worth of data and it returns what I would expect:

```<code>start = "2000-01-01"
end = "2000-12-01"

ggplot(data, aes(fill = cohort, x = dates, y = revenue)) +
    geom_bar(stat = "identity", position = position_dodge(width = NULL)) +
    xlab("Month") +
    ylab("Net Revenue") +
    geom_text(aes(label = round(revenue, 0)), vjust = -0.5, size = 3, position = position_dodge(width = 25)) +
    scale_x_date(date_breaks = "1 month", limits = as.Date(c(start, end))) +
    ggtitle("Monthly Revenue by Group") +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 60, hjust = 1), plot.title = element_text(hjust = 0.5)) +
    scale_fill_manual(values=c("#00BFC4", "#F8766D"))
</code>```

But if I expand the date range to two years or more and rerun the graph, it shows additional months on both sides of the x-axis despite not displaying any information on the y-axis.

```<code>start = "2000-01-01"
end = "2001-12-01"
#rerun the ggplot code from above
</code>```

Note the non-existant data points for 1999-12-01 and 2002-01-01. Why do these appear and how can I remove them?

答:
Many (all?) of the scale_* functions take expand= as an argument. It's common in R plots (both base and ggplot2) to expand the axes just a little bit (4% on each end, I believe), I think so that none of the lines/points are scrunched up against the "box" boundary.

If you include expand=c(0,0), you get what you want.

(BTW: you have mismatched parens. Fixed here.)

ggplot(data, aes(fill = cohort, x = dates, y = revenue)) +
    geom_bar(stat = "identity", position = position_dodge(width = NULL)) +
    xlab("Month") +
    ylab("Net Revenue") +
    geom_text(aes(label = round(revenue, 0)), vjust = -0.5, size = 3, position = position_dodge(width = 25)) +
    scale_x_date(date_breaks = "1 month", limits = as.Date(c(start, end)), expand = c(0, 0)) +
    ggtitle("Monthly Revenue by Group") +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 60, hjust = 1), plot.title = element_text(hjust = 0.5)) +
    scale_fill_manual(values=c("#00BFC4", "#F8766D"))
```

Body:
Here's some sample data for a company's Net revenue split by two cohorts:

data <- data.frame(dates = rep(seq(as.Date("2000/1/1"), by = "month", length.out = 48), each = 2),
                   revenue = rep(seq(10000, by = 1000, length.out = 48), each = 2) * rnorm(96, mean = 1, sd = 0.1),
                   cohort = c("Group 1", "Group 2"))

I can show one year's worth of data and it returns what I would expect:

start = "2000-01-01"
end = "2000-12-01"

ggplot(data, aes(fill = cohort, x = dates, y = revenue)) +
    geom_bar(stat = "identity", position = position_dodge(width = NULL)) +
    xlab("Month") +
    ylab("Net Revenue") +
    geom_text(aes(label = round(revenue, 0)), vjust = -0.5, size = 3, position = position_dodge(width = 25)) +
    scale_x_date(date_breaks = "1 month", limits = as.Date(c(start, end))) +
    ggtitle("Monthly Revenue by Group") +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 60, hjust = 1), plot.title = element_text(hjust = 0.5)) +
    scale_fill_manual(values=c("#00BFC4", "#F8766D"))

But if I expand the date range to two years or more and rerun the graph, it shows additional months on both sides of the x-axis despite not displaying any information on the y-axis.

start = "2000-01-01"
end = "2001-12-01"
#rerun the ggplot code from above

Note the non-existant data points for 1999-12-01 and 2002-01-01. Why do these appear and how can I remove them?


问:
Converting React to React Native
I have a React App that I need to convert to React Native. I do not have a lot of experience on web development, so i might be missing something essential here. The problem I have is that when I open the app in the emulator I only see a white page that says "Home" on top. This what i have translated of the code so far.

index.js

```<code>import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);
</code>```

App.js

```<code>import React from 'react';
import Routes from './src/core/Routes';
import configureStore from './src/services/store';
import {Provider} from 'react-redux';
import {View} from 'react-native';
import {createMuiTheme, MuiThemeProvider} from '@material-ui/core';
import {
    font_family_default,
    font_family_secondary,
    font_size_md,
    font_size_sm,
    font_weight_bold,
    font_weight_normal,
    font_weight_semi_bold,
} from './src/assets/style/variables';
import {rem} from './src/assets/style/functions';
import colors from './src/assets/style/colors';

const theme = createMuiTheme({
    typography: {
        fontFamily: font_family_default,
        fontSize: 16,
        fontWeightLight: font_weight_normal,
        fontWeightRegular: font_weight_semi_bold,
        fontWeightMedium: font_weight_bold,
    },
    overrides: {
        MuiMenuItem: {
            root: {
                fontSize: font_size_sm,
                fontFamily: font_family_secondary,
                fontWeight: font_weight_semi_bold,
                minHeight: rem(40),
            },
        },
        MuiMenu: {
            paper: {
                boxShadow: '0px 12px 56px -8px rgba(0,0,0,0.2)',
                borderRadius: `${rem(3)}`,
            },
        },
        MuiExpansionPanelSummary: {
            root: {
                padding: `0px ${rem(16)}`,
            },
            content: {
                margin: `${rem(8)} 0px `,
            },
        },
        MuiInputBase: {
            root: {
                fontSize: font_size_md,
            },
        },
        MuiPickersToolbar: {
            toolbar: {
                backgroundColor: colors.grey.primary,
            },
        },
        MuiPickersDay: {
            daySelected: {
                backgroundColor: colors.yellow.dark2,
                '&:hover': {
                    backgroundColor: colors.yellow.dark2,
                },
            },
        },

        MuiPickersClockNumber: {
            clockNumberSelected: {backgroundColor: colors.yellow.dark2},
        },

        MuiPickersClock: {
            pin: {backgroundColor: colors.yellow.dark2},
        },
        MuiPickersClockPointer: {
            pointer: {backgroundColor: colors.yellow.dark2},
            thumb: {border: `14px solid ${colors.yellow.dark2}`},
        },
    },
});

const store = configureStore();

const App: () => React$Node = () => {
    return (
        <Provider store={store}>
            <MuiThemeProvider theme={theme}>
                <View style={{flex: 1}}>
                    <Routes/>
                </View>
            </MuiThemeProvider>
        </Provider>
    );
};

export default App;
</code>```

Routes.js

```<code>import React from 'react';
import {Router, Scene} from 'react-native-router-flux';
import Login from '../pages/login';

const Routes = () => (
    <Router>
        <Scene key="root">
            <Scene key="home" component={Login} title="Home" initial={true}/>
        </Scene>
    </Router>
);

export default Routes;
</code>```

/src/page/login/index.js

```<code>import React, {useState} from 'react';
import styled from 'styled-components/native';
import Input from '../../shared/components/Input';
import Button from '../../shared/components/Button';
import {connect} from 'react-redux';
import {APP_ROUTES} from '../../core/global-constants';
import {Link, Redirect} from 'react-router-native';

import Logo from '../../assets/img/log.svg';
import colors from '../../assets/style/colors';
import {rem} from '../../assets/style/functions';
import {device, font_size_md, font_size_xxl, font_weight_normal} from '../../assets/style/variables';
import {login} from '../../services/actions/authenticationActions';
import useForm from '../../shared/hooks/useForm';
import validate from './loginFormValidations';

const theme = {
    backgroundColor: colors.white.light1,
};

function Login(props) {
    const {values, handleChange, handleSubmit, errors} = useForm(login, validate);
    const [redirect, setRedirect] = useState(false);
    const [errorLogin, setErrorLogin] = useState(false);

    function login() {
        if (Object.keys(errors).length === 0) {
            props.login(values).then(
                res => {
                    setRedirect(true);
                },
                err => {
                    errors.login = props.errorMessage
                        ? `${props.errorMessage},  please try again`
                        : `No active account found with the given credentials,  please try again`;
                    setErrorLogin(true);
                },
            );
        }
    }

    if (redirect) {
        return <Redirect to={APP_ROUTES.timeTracker}/>;
    }
    return (
        <Style.Section>
            <Style.Img src={Logo} alt="toki timer logo"/>
            <Style.Hero>
                <Style.Title>Welcome back!</Style.Title>
                <Style.Subtitle>Log in to continue</Style.Subtitle>
            </Style.Hero>
            <Style.Form onSubmit={handleSubmit}>
                <Style.FormGroup>
                    <Input
                        id="username"
                        name="username"
                        placeholder="Username"
                        backgroundColor={theme}
                        onChange={handleChange}
                        value={values.username || ''}
                        hasError={errors.username}
                    />
                    {errors.username && <Style.ErrorMessage>{errors.username}</Style.ErrorMessage>}
                </Style.FormGroup>

                <Style.FormGroup>
                    <Input
                        id="password"
                        name="password"
                        type="password"
                        placeholder="Password"
                        backgroundColor={theme}
                        onChange={handleChange}
                        value={values.password || ''}
                        hasError={errors.password}
                    />
                    {errors.password && <Style.ErrorMessage>{errors.password}</Style.ErrorMessage>}
                    {errorLogin && <Style.ErrorMessage>{errors.login}</Style.ErrorMessage>}
                </Style.FormGroup>
                <Button name="Login" type="submit"/>
            </Style.Form>
            <Style.Hero>
                <Style.BottomLinks>
                    <Style.Link to={APP_ROUTES.forgotPassword}>Forgot your password?</Style.Link>
                </Style.BottomLinks>
            </Style.Hero>
        </Style.Section>
    );
}

const mapStateToProps = state => {
    return {
        loading: state.authorization.loading,
        isAuthenticated: state.authorization.isAuthenticated,
        loginSuccess: state.authorization.loginSuccess,
        loginError: state.authorization.loginError,
        errorMessage: state.authorization.errorMessage,
        isAdmin: state.authorization.userInSession.isAdmin,
    };
};
const mapDispatchToProps = {login};

export default connect(
    mapStateToProps,
    mapDispatchToProps,
)(Login);

const Style = {};

Style.Section = styled.SectionList`
  background-color: ${colors.grey.primary};
  min-height: 100%;
  margin: 0px auto;
  display: flex;
  flex-direction: column;
`;
Style.Form = styled.View`
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 0 35%;
  margin-bottom: ${rem(40)};

  @media ${device.mobileS} {
    padding: 0 5%;
  }

  @media ${device.mobileL} {
    padding: 0 15%;
  }

  @media ${device.laptop} {
    padding: 0 35%;
  }
`;

Style.Hero = styled.View`
  display: flex;
  flex-direction: column;
  margin-bottom: ${rem(70)};
  align-items: center;
`;
Style.Title = styled.Text`
  color: ${colors.white.primary};
  font-size: ${font_size_xxl};
  font-weight: ${font_weight_normal};
  margin: 0;
`;
Style.Subtitle = styled(Style.Title)`
  font-size: ${font_size_md};
`;
Style.Img = styled.Image`
  margin-bottom: ${rem(60)};
  margin-top: ${rem(60)};
`;
Style.BottomLinks = styled.Text`
  color: ${colors.white.primary};
  margin-top: ${rem(10)};
`;

Style.Link = styled(Link)`
  color: ${colors.yellow.primary};

  &:hover {
    text-decoration: underline;
  }
`;
Style.FormGroup = styled.View`
  margin-bottom: ${rem(45)};
`;
Style.ErrorMessage = styled.Text`
  font-size: ${font_size_md};
  color: ${colors.red.primary};
`;
</code>```

What I don't seem to understand after reading documentation is how routing works, for example, using react, my Routes.js looks like this:

```<code>import React from 'react'
import { Switch, Route } from 'react-router-dom'

import { APP_ROUTES } from './global-constants'
import Login from '../pages/login'
import Dashboard from '../pages/dashboard'
import TimeTracker from '../pages/time-tracker'
import SignUp from '../pages/signUp'
import PrivateRoute from '../shared/components/PrivateRoute'
import UserList from '../pages/user-list'
import DepartmentsList from '../pages/departments-list'
import Reports from '../pages/reports'
import UserProfile from '../pages/user-profile'
import ForgotPassword from '../pages/forgot-password'
import NotFound from '../shared/components/NotFound'

const Routes = () => (
  <main>
    <Switch>
      <Route exact path={[APP_ROUTES.home, APP_ROUTES.login]} component={Login} />
      <Route exact path={APP_ROUTES.signUp} component={SignUp} />
      <Route exact path={APP_ROUTES.forgotPassword} component={ForgotPassword} />
      <PrivateRoute
        exact
        path={[APP_ROUTES.dashboard, APP_ROUTES.dashboardDeparment]}
        component={Dashboard}
      />
      <PrivateRoute exact path={APP_ROUTES.timeTracker} component={TimeTracker} />
      <PrivateRoute exact path={APP_ROUTES.usersList} component={UserList} />
      <PrivateRoute exact path={APP_ROUTES.departments} component={DepartmentsList} />
      <PrivateRoute exact path={APP_ROUTES.reports} component={Reports} />
      <PrivateRoute exact path={APP_ROUTES.userDetails} component={UserProfile} />
      <PrivateRoute component={NotFound} />
    </Switch>
  </main>
)

export default Routes
</code>```

I made the changes to the routes file since I've read that react-router-dom does not work in native. My main purpose is to re-use as much code as possible, but if I can't, what do I need to change for the page to actually show in the emulator?

答:
You cannot reuse the 'Render' part of React (Web) into his Native Solution, because it uses a different approvach to generate the views. At first glance they looks, as both uses the same syntactic format, implementing "Tags" for generate the render tree.

But the difference here is that both solutions differs on how those "Tags" are implemented. While React (Web) translate them to the well know HTML5 Standard tags, the "Native" translate those to equivalent platform-native components. For this reason, they must be very abstract to provide an adequate abstraction layer to achieve the "Single Codebase / Multiplatform" premise.

The concept of Components, Props and States keeps intact. Also, the 'Style' logic isn't the same (Although is kinda CSS inspired)

Making some research i found that the 'Material-UI' Library is only React (Web) supported, so you must migrate to another solution to apply the desired UI Style. I would recommend search on Awesome React Native which is an curated index for some of the most popular React Native Components.

About the Routing part, you're using two different libraries: 'react-router-dom' and 'react-native-router-flux'. The first one isn't Native Compatible, but haves a compatible version. However, you'll must discard one of them to avoid collitions.

Also i recommend you this 'React to React Native' Article which provides some important aspects to consider through the migration process:
From React to React Native — What you need to know to jump ship

Title: Converting React to React Native

Body:
I have a React App that I need to convert to React Native. I do not have a lot of experience on web development, so i might be missing something essential here. The problem I have is that when I open the app in the emulator I only see a white page that says "Home" on top. This what i have translated of the code so far.

index.js

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

App.js

import React from 'react';
import Routes from './src/core/Routes';
import configureStore from './src/services/store';
import {Provider} from 'react-redux';
import {View} from 'react-native';
import {createMuiTheme, MuiThemeProvider} from '@material-ui/core';
import {
    font_family_default,
    font_family_secondary,
    font_size_md,
    font_size_sm,
    font_weight_bold,
    font_weight_normal,
    font_weight_semi_bold,
} from './src/assets/style/variables';
import {rem} from './src/assets/style/functions';
import colors from './src/assets/style/colors';

const theme = createMuiTheme({
    typography: {
        fontFamily: font_family_default,
        fontSize: 16,
        fontWeightLight: font_weight_normal,
        fontWeightRegular: font_weight_semi_bold,
        fontWeightMedium: font_weight_bold,
    },
    overrides: {
        MuiMenuItem: {
            root: {
                fontSize: font_size_sm,
                fontFamily: font_family_secondary,
                fontWeight: font_weight_semi_bold,
                minHeight: rem(40),
            },
        },
        MuiMenu: {
            paper: {
                boxShadow: '0px 12px 56px -8px rgba(0,0,0,0.2)',
                borderRadius: `${rem(3)}`,
            },
        },
        MuiExpansionPanelSummary: {
            root: {
                padding: `0px ${rem(16)}`,
            },
            content: {
                margin: `${rem(8)} 0px `,
            },
        },
        MuiInputBase: {
            root: {
                fontSize: font_size_md,
            },
        },
        MuiPickersToolbar: {
            toolbar: {
                backgroundColor: colors.grey.primary,
            },
        },
        MuiPickersDay: {
            daySelected: {
                backgroundColor: colors.yellow.dark2,
                '&:hover': {
                    backgroundColor: colors.yellow.dark2,
                },
            },
        },

        MuiPickersClockNumber: {
            clockNumberSelected: {backgroundColor: colors.yellow.dark2},
        },

        MuiPickersClock: {
            pin: {backgroundColor: colors.yellow.dark2},
        },
        MuiPickersClockPointer: {
            pointer: {backgroundColor: colors.yellow.dark2},
            thumb: {border: `14px solid ${colors.yellow.dark2}`},
        },
    },
});

const store = configureStore();

const App: () => React$Node = () => {
    return (
        <Provider store={store}>
            <MuiThemeProvider theme={theme}>
                <View style={{flex: 1}}>
                    <Routes/>
                </View>
            </MuiThemeProvider>
        </Provider>
    );
};

export default App;

Routes.js

import React from 'react';
import {Router, Scene} from 'react-native-router-flux';
import Login from '../pages/login';

const Routes = () => (
    <Router>
        <Scene key="root">
            <Scene key="home" component={Login} title="Home" initial={true}/>
        </Scene>
    </Router>
);

export default Routes;

/src/page/login/index.js

import React, {useState} from 'react';
import styled from 'styled-components/native';
import Input from '../../shared/components/Input';
import Button from '../../shared/components/Button';
import {connect} from 'react-redux';
import {APP_ROUTES} from '../../core/global-constants';
import {Link, Redirect} from 'react-router-native';

import Logo from '../../assets/img/log.svg';
import colors from '../../assets/style/colors';
import {rem} from '../../assets/style/functions';
import {device, font_size_md, font_size_xxl, font_weight_normal} from '../../assets/style/variables';
import {login} from '../../services/actions/authenticationActions';
import useForm from '../../shared/hooks/useForm';
import validate from './loginFormValidations';

const theme = {
    backgroundColor: colors.white.light1,
};

function Login(props) {
    const {values, handleChange, handleSubmit, errors} = useForm(login, validate);
    const [redirect, setRedirect] = useState(false);
    const [errorLogin, setErrorLogin] = useState(false);

    function login() {
        if (Object.keys(errors).length === 0) {
            props.login(values).then(
                res => {
                    setRedirect(true);
                },
                err => {
                    errors.login = props.errorMessage
                        ? `${props.errorMessage},  please try again`
                        : `No active account found with the given credentials,  please try again`;
                    setErrorLogin(true);
                },
            );
        }
    }

    if (redirect) {
        return <Redirect to={APP_ROUTES.timeTracker}/>;
    }
    return (

            </Style.Hero>
            }
                </Style.FormGroup>

                }
                    {errorLogin && }
                </Style.FormGroup>
                <Button name="Login" type="submit"/>
            </Style.Form>

                </Style.BottomLinks>
            </Style.Hero>
        </Style.Section>
    );
}

const mapStateToProps = state => {
    return {
        loading: state.authorization.loading,
        isAuthenticated: state.authorization.isAuthenticated,
        loginSuccess: state.authorization.loginSuccess,
        loginError: state.authorization.loginError,
        errorMessage: state.authorization.errorMessage,
        isAdmin: state.authorization.userInSession.isAdmin,
    };
};
const mapDispatchToProps = {login};

export default connect(
    mapStateToProps,
    mapDispatchToProps,
)(Login);

const Style = {};

Style.Section = styled.SectionList`
  background-color: ${colors.grey.primary};
  min-height: 100%;
  margin: 0px auto;
  display: flex;
  flex-direction: column;
`;
Style.Form = styled.View`
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 0 35%;
  margin-bottom: ${rem(40)};

  @media ${device.mobileS} {
    padding: 0 5%;
  }

  @media ${device.mobileL} {
    padding: 0 15%;
  }

  @media ${device.laptop} {
    padding: 0 35%;
  }
`;

Style.Hero = styled.View`
  display: flex;
  flex-direction: column;
  margin-bottom: ${rem(70)};
  align-items: center;
`;
Style.Title = styled.Text`
  color: ${colors.white.primary};
  font-size: ${font_size_xxl};
  font-weight: ${font_weight_normal};
  margin: 0;
`;
Style.Subtitle = styled(Style.Title)`
  font-size: ${font_size_md};
`;
Style.Img = styled.Image`
  margin-bottom: ${rem(60)};
  margin-top: ${rem(60)};
`;
Style.BottomLinks = styled.Text`
  color: ${colors.white.primary};
  margin-top: ${rem(10)};
`;

Style.Link = styled(Link)`
  color: ${colors.yellow.primary};

  &:hover {
    text-decoration: underline;
  }
`;
Style.FormGroup = styled.View`
  margin-bottom: ${rem(45)};
`;
Style.ErrorMessage = styled.Text`
  font-size: ${font_size_md};
  color: ${colors.red.primary};
`;

What I don't seem to understand after reading documentation is how routing works, for example, using react, my Routes.js looks like this:

import React from 'react'
import { Switch, Route } from 'react-router-dom'

import { APP_ROUTES } from './global-constants'
import Login from '../pages/login'
import Dashboard from '../pages/dashboard'
import TimeTracker from '../pages/time-tracker'
import SignUp from '../pages/signUp'
import PrivateRoute from '../shared/components/PrivateRoute'
import UserList from '../pages/user-list'
import DepartmentsList from '../pages/departments-list'
import Reports from '../pages/reports'
import UserProfile from '../pages/user-profile'
import ForgotPassword from '../pages/forgot-password'
import NotFound from '../shared/components/NotFound'

const Routes = () => (

    <Switch>
      <Route exact path={[APP_ROUTES.home, APP_ROUTES.login]} component={Login} />
      <Route exact path={APP_ROUTES.signUp} component={SignUp} />
      <Route exact path={APP_ROUTES.forgotPassword} component={ForgotPassword} />
      <PrivateRoute
        exact
        path={[APP_ROUTES.dashboard, APP_ROUTES.dashboardDeparment]}
        component={Dashboard}
      />
      <PrivateRoute exact path={APP_ROUTES.timeTracker} component={TimeTracker} />
      <PrivateRoute exact path={APP_ROUTES.usersList} component={UserList} />
      <PrivateRoute exact path={APP_ROUTES.departments} component={DepartmentsList} />
      <PrivateRoute exact path={APP_ROUTES.reports} component={Reports} />
      <PrivateRoute exact path={APP_ROUTES.userDetails} component={UserProfile} />
      <PrivateRoute component={NotFound} />
    </Switch>

)

export default Routes

I made the changes to the routes file since I've read that react-router-dom does not work in native. My main purpose is to re-use as much code as possible, but if I can't, what do I need to change for the page to actually show in the emulator?


问:
Silent push notification (background) not received on macOS Catalina (Mac Catalyst app)
I'm currently implementing push notifications from our backend server to our app (macOS Catalina & iOS - same code base), using Apple Push Notifications & the token based way of authentication (generating JWT from keyId, teamId, ... & signing it with the private key generated in the Apple developer console) to send pushes to APN service.

The problem I am facing is that I can successfully send "alert" notifications (status 200, with header apns-push-type: alert) and receive them on my iOS and MacOS device (the push notifications appear successfully in production and sandbox mode) but for some reason, "silent" pushes (with header apns-push-type: background) are only received on my iOS device (iPhone), but not on my Mac (didReceiveRemoteNotification(...) in AppDelegate is never called).

What I have done so far:

Made sure APN request header is correctly configured for silent push: apns-push-type: background

Made sure to have the correct APN topic header: apns-topic: my.bundle.id (this is different for sandbox/production)

Added the "semi-required" priority header: apns-priority: 5 (only when delivering background pushes)

Verified that the created JWT is valid and used in the APN auth header: authorization: mytoken (this must be the case, otherwise APN service would not respond with status 200)

Confirmed that my application has the correct entitlements & capabilities defined in Xcode (my reasoning: this must be the case, otherwise 'alert' push notifications would also not work)

Double checked that push notifications for the Mac app are allowed/enabled (checked system settings)

Made sure the device token im sending the push to is actually from the device intended to receive the push (e.g. my MacBook)

Checked that the private key I'm using to sign the JWT has the APN capability

Tested while the Mac app is running but not in focus & also when in focus

The APNs requests I am performing to send the push are:

Sandbox: POST https://api.sandbox.push.apple.com/3/device/{deviceToken}

Production: POST https://api.push.apple.com/3/device/{deviceToken}

The payload (JSON) I'm sending to APN service in the request body looks as follows:

```<code>{
   "aps": {
      "content-available": 1 # defines push as "silent"
   },
   "data": { #some key-value pairs here }
}
</code>```

In any case (both production & sandbox, both with the device token of iOS and macOS), my request to APN returns with a status code 200. My MacBook is running Catalina 10.15.3. What am I possibly doing wrong here or is that something that is simply not supported for Catalyst apps?

答:
Wow doozy question. I'm reasonably familiar with APNs headaches but something popped out at me from the latest docs:

Additionally, the notification’s POST request should contain the
  apns-push-type header field with a value of background, and the
  apns-priority field with a value of 5. The APNs server requires the
  apns-push-type field when sending push notifications to Apple Watch,
  and recommends it for all platforms. For more information, see Create
  and Send a POST Request to APNs.

Does the priority 5 thing make a difference?

Also my usually attempt to fix these problems is to test in an archive as opposed to an Xcode build. AFAIK the prod push server can only send to App Store, ad-hoc, enterprise, or testflight builds, so if you're just building from Xcode I don't think you'd get any push notifications with production apns.

Body:
I'm currently implementing push notifications from our backend server to our app (macOS Catalina & iOS - same code base), using Apple Push Notifications & the token based way of authentication (generating JWT from keyId, teamId, ... & signing it with the private key generated in the Apple developer console) to send pushes to APN service.

The problem I am facing is that I can successfully send "alert" notifications (status 200, with header apns-push-type: alert) and receive them on my iOS and MacOS device (the push notifications appear successfully in production and sandbox mode) but for some reason, "silent" pushes (with header apns-push-type: background) are only received on my iOS device (iPhone), but not on my Mac (didReceiveRemoteNotification(...) in AppDelegate is never called).

What I have done so far:

Made sure APN request header is correctly configured for silent push: apns-push-type: background

Made sure to have the correct APN topic header: apns-topic: my.bundle.id (this is different for sandbox/production)

Added the "semi-required" priority header: apns-priority: 5 (only when delivering background pushes)

Verified that the created JWT is valid and used in the APN auth header: authorization: mytoken (this must be the case, otherwise APN service would not respond with status 200)

Confirmed that my application has the correct entitlements & capabilities defined in Xcode (my reasoning: this must be the case, otherwise 'alert' push notifications would also not work)

Double checked that push notifications for the Mac app are allowed/enabled (checked system settings)

Made sure the device token im sending the push to is actually from the device intended to receive the push (e.g. my MacBook)

Checked that the private key I'm using to sign the JWT has the APN capability

Tested while the Mac app is running but not in focus & also when in focus

The APNs requests I am performing to send the push are:

Sandbox: POST https://api.sandbox.push.apple.com/3/device/{deviceToken}

Production: POST https://api.push.apple.com/3/device/{deviceToken}

The payload (JSON) I'm sending to APN service in the request body looks as follows:

{
   "aps": {
      "content-available": 1 # defines push as "silent"
   },
   "data": { #some key-value pairs here }
}

In any case (both production & sandbox, both with the device token of iOS and macOS), my request to APN returns with a status code 200. My MacBook is running Catalina 10.15.3. What am I possibly doing wrong here or is that something that is simply not supported for Catalyst apps?


问:
Box for Text Not Working?
On this page, I'm trying to create a text box around the paragraph that begins "It's important not to...". I used this CSS:

```<code>.transbox  {
    background: #F5FBEF;
    border: 1px solid #E3F6CE;
    padding: 10px;
    margin: 10px auto;
}
</code>```

The text has moved slightly out of line with the other text in the article, but it's not showing how it's supposed to. Any ideas what's wrong?

答:
Your .transbox styles are within CSS comment tags, that is why they are not showing up. Move the styles out of the /* */ tags.

Also, you should note that there are no paragraph tags within the box itself, so .transbox p will not work.

ContentLicense: CC BY-SA 3.0

Title: Box for Text Not Working?

Body:
On this page, I'm trying to create a text box around the paragraph that begins "It's important not to...". I used this CSS:

.transbox  {
    background: #F5FBEF;
    border: 1px solid #E3F6CE;
    padding: 10px;
    margin: 10px auto;
}

The text has moved slightly out of line with the other text in the article, but it's not showing how it's supposed to. Any ideas what's wrong?


问:
How can I route to login if canLoad or canActivate fails, without routing in AuthGuard itself?
So, this is what my AuthGuard looks like:

```<code>canLoad(route: Route) {
    return this.store.select(fromRoot.getIsAuth).pipe(take(1));
}
</code>```

I check Authentication information from app.component and simply return an Observable boolean.

I don't want to subscribe to this to reroute, I don't want to use router.navigate inside AuthGuard so I want to keep it a simple Guard.

Is there a way to reroute inside routing-module, that simply routes to an alternate path if AuthGuard returns false?

答:
TLDR; If you navigate directly inside OnLoad you'll get a NavigationCancel event with a message about a mismatched ID (and I HATE that error!). You can avoid it like this :

```<code>this.routerEvents.navigationCancel$.pipe(take(1)).subscribe(() =>
{
      this.router.navigateByUrl(result);
});

return false;
</code>```

I'm not sure exactly when most people are using canLoad vs. canActivate but my specific case (and solution) is as follows:

I have a login dialog that gets displayed from inside my AuthGuard service. The AuthGuard shows the dialog but does not return true/false until the user has tried to log in.

The AuthGuard service returns UrlTree if the login fails and the user needs to be redirected to a particular page (such as support page)

My '/account` route is lazy loaded and may take a couple seconds to load

I want the login dialog to appear instantly when the user clicks 'Account' hence adding CanLoad

Therefore what I did was to put the same logic into my canLoad handler. This means the canLoad will also show a dialog box if it gets hit first.

I left my canActivate guard to run the exact same logic (don't worry - you won't ever see two dialogs)

For this case I found it easiest to do the following in canLoad:

```<code>canLoad(route: Route, segments: UrlSegment[])
   {
       const currentNavigation = this.router.getCurrentNavigation();
       const isInitialNavigation = !currentNavigation.previousNavigation;

       if (isInitialNavigation)
       {
           return true;   // always allow load for first navigation (avoids other complications)
       }
       else {

           // returns Observable<boolean | UrlTree>
           return showLoginDialog().pipe(map(result => {

               if (typeof result === 'boolean') {
                  return result;
               }
               else {
                     // we have a URL tree
                    // wait for the expected NavigationCancel event and then navigate
                    this.routerEvents.navigationCancel$.pipe(take(1)).subscribe(() =>
                    {
                       this.router.navigateByUrl(result);
                    });
                   return false;
                }
           });;
       }
}
</code>```

I also have a root provided RouterEvents service where I define

```<code>  navigationCancel$ = this.router.events.pipe(filter((e): e is NavigationCancel => e instanceof NavigationCancel));
</code>```

Note: watch out if you choose not to include the isInitialNavigation check. If your redirect is trying to redirect to the homepage then it won't work because the router thinks you're already there. You can solve this with a /redirect_home route that just redirects to homepage - or change the onSameURLNavigation setting.

Body:
So, this is what my AuthGuard looks like:

canLoad(route: Route) {
    return this.store.select(fromRoot.getIsAuth).pipe(take(1));
}

I check Authentication information from app.component and simply return an Observable boolean.

I don't want to subscribe to this to reroute, I don't want to use router.navigate inside AuthGuard so I want to keep it a simple Guard.

Is there a way to reroute inside routing-module, that simply routes to an alternate path if AuthGuard returns false?

Body:
TLDR; If you navigate directly inside OnLoad you'll get a NavigationCancel event with a message about a mismatched ID (and I HATE that error!). You can avoid it like this :

this.routerEvents.navigationCancel$.pipe(take(1)).subscribe(() =>
{
      this.router.navigateByUrl(result);
});

return false;

I'm not sure exactly when most people are using canLoad vs. canActivate but my specific case (and solution) is as follows:

I have a login dialog that gets displayed from inside my AuthGuard service. The AuthGuard shows the dialog but does not return true/false until the user has tried to log in.

The AuthGuard service returns UrlTree if the login fails and the user needs to be redirected to a particular page (such as support page)

My '/account` route is lazy loaded and may take a couple seconds to load

I want the login dialog to appear instantly when the user clicks 'Account' hence adding CanLoad

Therefore what I did was to put the same logic into my canLoad handler. This means the canLoad will also show a dialog box if it gets hit first.

I left my canActivate guard to run the exact same logic (don't worry - you won't ever see two dialogs)

For this case I found it easiest to do the following in canLoad:

canLoad(route: Route, segments: UrlSegment[])
   {
       const currentNavigation = this.router.getCurrentNavigation();
       const isInitialNavigation = !currentNavigation.previousNavigation;

       if (isInitialNavigation)
       {
           return true;   // always allow load for first navigation (avoids other complications)
       }
       else {

           // returns Observable<boolean | UrlTree>
           return showLoginDialog().pipe(map(result => {

               if (typeof result === 'boolean') {
                  return result;
               }
               else {
                     // we have a URL tree
                    // wait for the expected NavigationCancel event and then navigate
                    this.routerEvents.navigationCancel$.pipe(take(1)).subscribe(() =>
                    {
                       this.router.navigateByUrl(result);
                    });
                   return false;
                }
           });;
       }
}

I also have a root provided RouterEvents service where I define

  navigationCancel$ = this.router.events.pipe(filter((e): e is NavigationCancel => e instanceof NavigationCancel));

Note: watch out if you choose not to include the isInitialNavigation check. If your redirect is trying to redirect to the homepage then it won't work because the router thinks you're already there. You can solve this with a /redirect_home route that just redirects to homepage - or change the onSameURLNavigation setting.


问:
Converting Windows Path to Linux
I created a CSV file (driving_log.csv) for the filepath of each image that my simulator created but I was using my brother's Windows computer when I did that so now the file path looks like this for each image (and there is almost 14000 of them).  I get an error when invoking it from my file.py, which is in the same directory as the CSV file.

```<code>C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\center_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\left_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\right_2020_02_08_14_16_38_988.jpg,0,0,0,7.918889E-06
</code>```

I'm using Arch Linux.  I want to iterate through each line and change it to this:

```<code>/home/onur/Documents/behavioral-cloning-CARLA/IMG/center_2020_02_08_14_16_38_988.jpg,left_2020_02_08_14_16_38_988.jpg,right_2020_02_08_14_16_38_988.jpg,0,0,0,7.918889E-06
</code>```

As you can see, I need everything that comes after \IMG\.

What is the best way to go about this?  Should I just slice each string at IMG\ and take what's after it or use regex?

I've tried this for this specific line to see if it works but it doesn't:

```<code>string = r"C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\center_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\left_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\right_2020_02_08_14_16_38_988.jpg,0,0,0,7.918889E-06 "

new_string = string.replace(r"'C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\'", r"'/home/onur/Documents/behavioral-cloning-CARLA/IMG/'", 3)

print(new_string)
</code>```

This is the output:

```<code>C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\center_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\left_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\right_2020_02_08_14_16_38_988.jpg,0,0,0,7.918889E-06
</code>```

答:
If you are running your code on a *nix machine, you can use the PureWindowsPath class:

```<code>>>> from pathlib import PureWindowsPath, PurePosixPath
>>> path = PureWindowsPath('C:\\Users\\foo\\bar')

>>> path.parts
('c:\\', 'Users', 'foo', 'bar')

>>> PurePosixPath('/usr', *path.parts[2:])
PurePosixPath('/usr/foo/bar')
</code>```

You can apply the string replace method to every line in a text file as follows:

```<code>with open("input.csv", "r") as f_in:
    with open("output.csv", "w") as f_out:
        for line in f_in:
            new_line = line.replace(...)  # magic goes here
            f_out.write("{}\n".format(new_line))
</code>```

Title: Converting Windows Path to Linux

Body:
I created a CSV file (driving_log.csv) for the filepath of each image that my simulator created but I was using my brother's Windows computer when I did that so now the file path looks like this for each image (and there is almost 14000 of them).  I get an error when invoking it from my file.py, which is in the same directory as the CSV file.

C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\center_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\left_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\right_2020_02_08_14_16_38_988.jpg,0,0,0,7.918889E-06

I'm using Arch Linux.  I want to iterate through each line and change it to this:

/home/onur/Documents/behavioral-cloning-CARLA/IMG/center_2020_02_08_14_16_38_988.jpg,left_2020_02_08_14_16_38_988.jpg,right_2020_02_08_14_16_38_988.jpg,0,0,0,7.918889E-06

As you can see, I need everything that comes after \IMG\.

What is the best way to go about this?  Should I just slice each string at IMG\ and take what's after it or use regex?

I've tried this for this specific line to see if it works but it doesn't:

string = r"C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\center_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\left_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\right_2020_02_08_14_16_38_988.jpg,0,0,0,7.918889E-06 "

new_string = string.replace(r"'C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\'", r"'/home/onur/Documents/behavioral-cloning-CARLA/IMG/'", 3)

print(new_string)

This is the output:

C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\center_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\left_2020_02_08_14_16_38_988.jpg,C:\Users\a-ozb\Desktop\onur\behavirol-cloning-carla\IMG\right_2020_02_08_14_16_38_988.jpg,0,0,0,7.918889E-06

Body:
If you are running your code on a *nix machine, you can use the PureWindowsPath class:

>>> from pathlib import PureWindowsPath, PurePosixPath
>>> path = PureWindowsPath('C:\\Users\\foo\\bar')

>>> path.parts
('c:\\', 'Users', 'foo', 'bar')

>>> PurePosixPath('/usr', *path.parts[2:])
PurePosixPath('/usr/foo/bar')

You can apply the string replace method to every line in a text file as follows:

with open("input.csv", "r") as f_in:
    with open("output.csv", "w") as f_out:
        for line in f_in:
            new_line = line.replace(...)  # magic goes here
            f_out.write("{}\n".format(new_line))


问:
Navigating to child route with route parameter in relation to current route - Angular 8
I want to achieve this:

```<code><button [routerLink]="['deepRoute', deepRouteId]">Deep Route</button>
</code>```

But though an Angular (click) event, from any route (including child routes), like this:

```<code><button (click)="navigateToDeepRoute(deepRouteId)">Deep Route</button>
</code>```

Relevant routing code in my app-routing.module.ts:

```<code>const routes: Routes = [
{
  path: 'mainRoute',
  component: MainRouteComponent,
  children: [
    {
      path: 'childRoute/:childRouteId',
      component: ChildRouteComponent,
      children: [
        {
          path: 'deepRoute/:deepRouteId'
          component: DeepRouteComponent
        }
      ]
    }
  ]
}
....
</code>```

Given my routing, I'm currently in the ChildRouteComponent:

example.com/mainRoute/childRoute/1

And would like to navigate to:

example.com/mainRoute/childRoute/1/deepRoute/2

Inside my ChildRouteComponent, I have my navigation method:

```<code>navigateToDeepRoute(deepRouteId) {
  this.router.navigate(['deeperPath', { deepRouteId: deepRouteId}, { relativeTo: this.route.parent } ]);
}
</code>```

But it's not working..

I've also tried:

```<code>this.router.navigate(['deeperPath', { deepRouteId: deepRouteId } ], { relativeTo: this.route } );
</code>```

And..

```<code>this.router.navigate(['../deeperPath', { deepRouteId: deepRouteId }, { relativeTo: this.route.parent } ]);
</code>```

But still, no cigar. Any advice?

答:
```<code>navigateToDeepRoute(deepRouteId) {
  this.router.navigate(['deeperPath', deepRouteId, { relativeTo: this.route } ]);
}
</code>```

or

```<code>navigateToDeepRoute(deepRouteId) {
  this.router.navigate([`deeperPath/${deepRouteId}`, { relativeTo: this.route } ]);
}
</code>```

You don't need to provide the object.

Body:
I want to achieve this:

<button [routerLink]="['deepRoute', deepRouteId]">Deep Route</button>

But though an Angular (click) event, from any route (including child routes), like this:

<button (click)="navigateToDeepRoute(deepRouteId)">Deep Route</button>

Relevant routing code in my app-routing.module.ts:

const routes: Routes = [
{
  path: 'mainRoute',
  component: MainRouteComponent,
  children: [
    {
      path: 'childRoute/:childRouteId',
      component: ChildRouteComponent,
      children: [
        {
          path: 'deepRoute/:deepRouteId'
          component: DeepRouteComponent
        }
      ]
    }
  ]
}
....

Given my routing, I'm currently in the ChildRouteComponent:

example.com/mainRoute/childRoute/1

And would like to navigate to:

example.com/mainRoute/childRoute/1/deepRoute/2

Inside my ChildRouteComponent, I have my navigation method:

navigateToDeepRoute(deepRouteId) {
  this.router.navigate(['deeperPath', { deepRouteId: deepRouteId}, { relativeTo: this.route.parent } ]);
}

But it's not working..

I've also tried:

this.router.navigate(['deeperPath', { deepRouteId: deepRouteId } ], { relativeTo: this.route } );

And..

this.router.navigate(['../deeperPath', { deepRouteId: deepRouteId }, { relativeTo: this.route.parent } ]);

But still, no cigar. Any advice?

Body:
navigateToDeepRoute(deepRouteId) {
  this.router.navigate(['deeperPath', deepRouteId, { relativeTo: this.route } ]);
}

or

navigateToDeepRoute(deepRouteId) {
  this.router.navigate([`deeperPath/${deepRouteId}`, { relativeTo: this.route } ]);
}

You don't need to provide the object.


问:
Get pandas row names if value in pandas row is present
I am trying to convert a one hot key dataframe into a 2 d frame

Is there anyways I can iterate over rows and columns and fill the values having a 1 with the column name.

problem dataframe:

```<code>+------------------+-----+-----+
| sentence         | lor | sor |
+------------------+-----+-----+
| sam lived here   | 0   | 1   |
+------------------+-----+-----+
| drack lived here | 1   | 0   |
+------------------+-----+-----+

</code>```

Solution dataframe:

```<code>+------------------+------+
| sentence         | tags |
+------------------+------+
| sam lived here   | sor  |
+------------------+------+
| drack lived here | lor  |
+------------------+------+
</code>```

答:
You can segregate the rows having 1 for every column. For these columns, replace the value 1 with the name specified along with renaming the column names

```<code>lor_df = df.loc[df["lor"].eq(1), "lor"].rename(columns={"lor": "tags"}).replace(1, "lor")
sor_df = df.loc[df["sor"].eq(1), "sor"].rename(columns={"sor": "tags"}).replace(1, "sor")
</code>```

After this, concatenate the individual results using pandas.concat, followed by dropping the columns which aren't required.

```<code>df["tags"] = pd.concat([lor_df, sor_df], sort=False)
df.drop(columns=["lor", "sor"], inplace=True)
</code>```

To ensure unique values we can use pandas.DataFrame.drop_duplicates

```<code>df.drop_duplicates(inplace=True)
print(df)
</code>```

Body:
I am trying to convert a one hot key dataframe into a 2 d frame

Is there anyways I can iterate over rows and columns and fill the values having a 1 with the column name.

problem dataframe:

+------------------+-----+-----+
| sentence         | lor | sor |
+------------------+-----+-----+
| sam lived here   | 0   | 1   |
+------------------+-----+-----+
| drack lived here | 1   | 0   |
+------------------+-----+-----+

Solution dataframe:

+------------------+------+
| sentence         | tags |
+------------------+------+
| sam lived here   | sor  |
+------------------+------+
| drack lived here | lor  |
+------------------+------+

Body:
You can segregate the rows having 1 for every column. For these columns, replace the value 1 with the name specified along with renaming the column names

lor_df = df.loc[df["lor"].eq(1), "lor"].rename(columns={"lor": "tags"}).replace(1, "lor")
sor_df = df.loc[df["sor"].eq(1), "sor"].rename(columns={"sor": "tags"}).replace(1, "sor")

After this, concatenate the individual results using pandas.concat, followed by dropping the columns which aren't required.

df["tags"] = pd.concat([lor_df, sor_df], sort=False)
df.drop(columns=["lor", "sor"], inplace=True)

To ensure unique values we can use pandas.DataFrame.drop_duplicates

df.drop_duplicates(inplace=True)
print(df)


问:
Can anyone tell me how to hide the contents of a text box
I have a drop down button named bank.
I have 3 text boxes named t1, t2 and t3
if i am not selecting any of the banks all the three text boxes should be enabled..

am getting it..
but my problem is..

first i have selected any one from the drop down button, and after some time i have changed it to choose bank(i.e; the 0th index).. but even then the data in text boxes are still there itself.. how to hide it..

答: You should clear the textboxes before selecting drop down item.You can write this clear stmts in drop down change event.</p>