From 84d90b1b3a3aa33680f464d1b51a9414cb4ed765 Mon Sep 17 00:00:00 2001
From: Xiao Gui <xgui3783@gmail.com>
Date: Wed, 22 May 2019 17:56:28 +0200
Subject: [PATCH] bugfix: failing single plugin manifest does not fail all

---
 .../atlasViewer.dataService.service.ts        | 41 +++--------------
 .../atlasViewer.pluginService.service.ts      | 44 +++++++++++++++++--
 2 files changed, 47 insertions(+), 38 deletions(-)

diff --git a/src/atlasViewer/atlasViewer.dataService.service.ts b/src/atlasViewer/atlasViewer.dataService.service.ts
index 7838de600..149b02e0a 100644
--- a/src/atlasViewer/atlasViewer.dataService.service.ts
+++ b/src/atlasViewer/atlasViewer.dataService.service.ts
@@ -1,9 +1,12 @@
 import { Injectable, OnDestroy } from "@angular/core";
-import { Store, select } from "@ngrx/store";
-import { ViewerStateInterface, FETCHED_TEMPLATE, DataEntry, FETCHED_DATAENTRIES, safeFilter, FETCHED_SPATIAL_DATA, UPDATE_SPATIAL_DATA } from "../services/stateStore.service";
-import { Subscription, combineLatest } from "rxjs";
+import { Store } from "@ngrx/store";
+import { ViewerStateInterface, FETCHED_TEMPLATE, FETCHED_SPATIAL_DATA, UPDATE_SPATIAL_DATA } from "../services/stateStore.service";
+import { Subscription } from "rxjs";
 import { AtlasViewerConstantsServices } from "./atlasViewer.constantService.service";
-import { PluginManifest } from "./atlasViewer.pluginService.service";
+
+/**
+ * TODO move constructor into else where and deprecate ASAP
+ */
 
 @Injectable({
   providedIn : 'root'
@@ -11,36 +14,6 @@ import { PluginManifest } from "./atlasViewer.pluginService.service";
 export class AtlasViewerDataService implements OnDestroy{
   
   private subscriptions : Subscription[] = []
-
-  /**
-   * TODO ensure 
-   */
-  public promiseFetchedPluginManifests : Promise<PluginManifest[]> = new Promise((resolve,reject)=>{
-    Promise.all([
-      PLUGINDEV
-        ? fetch(PLUGINDEV).then(res => res.json())
-        : Promise.resolve([]),
-      new Promise(resolve => {
-        fetch(`${this.constantService.backendUrl}plugins`)
-          .then(res => res.json())
-          .then(arr => Promise.all(
-            arr.map(url => fetch(url).then(res => res.json()))
-          ))
-          .then(resolve)
-          .catch(e => {
-            resolve([])
-          })
-      }),
-      Promise.all(
-        BUNDLEDPLUGINS
-          .filter(v => typeof v === 'string')
-          .map(v => fetch(`res/plugin_examples/${v}/manifest.json`).then(res => res.json()))
-      )
-        .then(arr => arr.reduce((acc,curr) => acc.concat(curr) ,[]))
-    ])
-      .then(arr => resolve( [].concat(arr[0]).concat(arr[1]) ))
-      .catch(reject)
-  })
   
   constructor(
     private store : Store<ViewerStateInterface>,
diff --git a/src/atlasViewer/atlasViewer.pluginService.service.ts b/src/atlasViewer/atlasViewer.pluginService.service.ts
index 07be6886b..71f72b5b5 100644
--- a/src/atlasViewer/atlasViewer.pluginService.service.ts
+++ b/src/atlasViewer/atlasViewer.pluginService.service.ts
@@ -1,5 +1,4 @@
 import { Injectable, ViewContainerRef, ComponentFactoryResolver, ComponentFactory } from "@angular/core";
-import { AtlasViewerDataService } from "./atlasViewer.dataService.service";
 import { PluginInitManifestInterface, ACTION_TYPES } from "src/services/state/pluginState.store";
 import { isDefined } from 'src/services/stateStore.service'
 import { AtlasViewerAPIServices } from "./atlasViewer.apiService.service";
@@ -11,6 +10,7 @@ import { interval } from "rxjs";
 import { take, takeUntil } from "rxjs/operators";
 import { Store } from "@ngrx/store";
 import { WidgetUnit } from "./widgetUnit/widgetUnit.component";
+import { AtlasViewerConstantsServices } from "./atlasViewer.constantService.service";
 
 @Injectable({
   providedIn : 'root'
@@ -25,7 +25,7 @@ export class PluginServices{
 
   constructor(
     private apiService : AtlasViewerAPIServices,
-    private atlasDataService : AtlasViewerDataService,
+    private constantService : AtlasViewerConstantsServices,
     private widgetService : WidgetServices,
     private cfr : ComponentFactoryResolver,
     private store : Store<PluginInitManifestInterface>
@@ -34,8 +34,44 @@ export class PluginServices{
     this.pluginUnitFactory = this.cfr.resolveComponentFactory( PluginUnit )
     this.apiService.interactiveViewer.uiHandle.launchNewWidget = this.launchNewWidget.bind(this) 
     
-
-    this.atlasDataService.promiseFetchedPluginManifests
+    const promiseFetchedPluginManifests : Promise<PluginManifest[]> = new Promise((resolve, reject) => {
+      Promise.all([
+        /**
+         * PLUGINDEV should return an array of 
+         */
+        PLUGINDEV
+          ? fetch(PLUGINDEV).then(res => res.json())
+          : Promise.resolve([]),
+        new Promise(resolve => {
+          fetch(`${this.constantService.backendUrl}plugins`)
+            .then(res => res.json())
+            .then(arr => Promise.all(
+              arr.map(url => new Promise(rs => 
+                /**
+                 * instead of failing all promises when fetching manifests, only fail those that fails to fetch
+                 */
+                fetch(url).then(res => res.json()).then(rs).catch(e => (console.log('fetching manifest error', e), rs(null))))
+              )
+            ))
+            .then(manifests => resolve(
+              manifests.filter(m => !!m)
+            ))
+            .catch(e => {
+              resolve([])
+            })
+        }),
+        Promise.all(
+          BUNDLEDPLUGINS
+            .filter(v => typeof v === 'string')
+            .map(v => fetch(`res/plugin_examples/${v}/manifest.json`).then(res => res.json()))
+        )
+          .then(arr => arr.reduce((acc,curr) => acc.concat(curr) ,[]))
+      ])
+        .then(arr => resolve( [].concat(arr[0]).concat(arr[1]) ))
+        .catch(reject)
+    })
+    
+    promiseFetchedPluginManifests
       .then(arr=>
         this.fetchedPluginManifests = arr)
       .catch(console.error)
-- 
GitLab