- Get Started
- Concepts
Working with Projects
Hub.js exposes a number of ways to work with Hub Projects. At the lowest level, you can simply import functions like createProject
, updateProject
etc, and work with them. This is ideal when you are looking to optimize the payload of an application which only needs to do a subset of operations.
The next level up is to use the HubProjectManager
class. This class is instantiated with either an ArcGISContextManager
or IArcGISContext
. If your application needs to have a long-lived HubProjectManager
then it's best to pass a reference to your app's ArcGISContextManager
instance, so that when authentication changes, the HubProjectManager
instance will have current information because of the shared reference.
For most applications, you can simply create a HubProjectManager
using the IArcGISContext
, do some operations, and then let the HubProjectManager
instance be disposed.
The final option is to use the Hub
class. We recommend this for scripting / automation tasks. Although you could build a web application using the Hub
class, it will likely result in a very large build since classes are much more complex to "tree shake" so your applicatin will get the entire Hub system, despite likely only needing a few functions.
In an Application
We expect that most applications will leverage the HubProjectManager
class, instantiated as needed with IArcGISContext
from the application's ArcGISContextManager.context
. The following example shows this pattern using Ember.js, but it would be generally the same in React etc.
Ember.js Example
Assuming the following routes in an app...
//...snip...
this.route("projects", function () {
this.route("project", { path: "/:project_id" }, function () {
this.route("edit");
});
this.route("edit", function () {
this.route("new");
});
});
//...snip...
Create a Project
To create a project in the /projects/edit/new
controller...
import Controller from "@ember/controller";
import { inject as service } from "@ember/service";
import { action } from "@ember/object";
import { HubProjectManager } from "@esri/hub-common";
export default class projectsEditNewController extends Controller {
// appSettings is a singleton service that holds an ArcGISContextManager instance
// and exposes an `IArcGISContext` on a `.context` property
@service appSettings;
@action
async createProject(project) {
// instantiate the project manager
const projectMgr = HubProjectManager.init(appSettings.context);
// create the project and return the IHubProject instance
return projectMgr.create(project);
}
}
Get a Project
In the /projects/:project_id
route, we get the project by id or slug
import Route from "@ember/routing/route";
import { inject as service } from "@ember/service";
import { HubProjectManager } from "@esri/hub-common";
export default class ProjectsProjectRoute extends Route {
@service appSettings;
model(params) {
const projectMgr = HubProjectManager.init(appSettings.context);
return projectMgr.get(params.project_id);
}
}
Update a Project
In the /projects/:project_id/edit
controller we update the project like this
import Controller from "@ember/controller";
import { inject as service } from "@ember/service";
import { action } from "@ember/object";
import { HubProjectManager } from "@esri/hub-common";
export default class projectEditController extends Controller {
@service appSettings;
@action
updateProject(project) {
const projectMgr = HubProjectManager.create(appSettings.context);
return projectMgr.update(project);
}
}
Automation Scripting
If you need to create or manage a series of projects, you can do this via Node.js.
This example assumes you are using NodeJS v13 or higher, and have set type: "module"
in your package.json
file, allowing the use of ES Modules import syntax.
import { Hub } from "@esri/hub-common";
// create Hub instance
const myHub = await Hub.create({
authOptions: { username: "casey", password: "abc123" },
});
// create a project
let project = myHub.projects.create({
name: "Smith Street Curb Replacement",
summary: "Replace/upgrade damaged curbs along Smith St. Scheduled for 2024",
status: "active",
culture: "en-us",
slug: "smith-st-2024",
tags: ["2024 Plan"],
});
console.info(`Created project ${project.name} owned by ${project.owner}`);
// assign a timeline and update
project.timeline = {
title: "Project Schedule",
timeframe: "Summer 2024",
description: "Key dates for design and construction",
stages: [
{
title: "Study Completed",
description: "Initial review of existing infrastructure",
icon: "check-circle-f",
timeframe: "Fall 2019",
id: 1638572046394,
status: "Complete",
isEditing: false,
leadingElement: false,
trailingElement: false,
},
{
title: "Environmental and Preliminary Design Completed",
timeframe: "Fall 2019",
description:
"Work with Federal Highway Administration to secure environmental approval of designs",
icon: "check-circle-f",
id: 1638572046399,
status: "Complete",
isEditing: false,
leadingElement: false,
trailingElement: false,
},
],
};
project = await myHub.projects.update(project);
// Destroy a project
await myHub.projects.destroy("3efbc7...");
In a Component
When working with Hub Projects in Components, import the lower-level functions instead of using the HubProjectManager
. This enables the Component build process to tree-shake out more code, resulting in a smaller build size.
Let's suppose you have a component that will fetch and display a project using either
the project's ID or slug. The component would have an attribute identifier
that can take the slug or item id.
<arcgis-hub-project-view identifier="dcdev-smith-st-2024" />
In the component, import the getProject
function from @esri/hub-common
, and use that in the lifecycle hooks to load the project.
import { getProject } from "@esri/hub-common";
async componentWillLoad() {
// Note context should be set on the element as `IArcGISContext`
if (!this.project && this.identifier && this.context) {
this.project = await getProject(this.identifier, this.context.requestOptions);
}
}