How to Build a Power Apps Code App and Connect It to Office 365 Users & Dataverse

How to Build a Power Apps Code App and Connect It to Office 365 Users & Dataverse

How to Build a Power Apps Code App and Connect It to Office 365 Users & Dataverse

A Complete Step-by-Step Professional Guide

Microsoft Power Apps has introduced a new capability called Code Apps, allowing developers to build fully customizable web applications using TypeScript, React, and Power Platform services. Code Apps combine the control of traditional web development with the power of the Dataverse and Power Platform ecosystem.

In this guide, we will walk step-by-step through:

  1. Creating a Power Apps Code App
  2. Connecting the app to Office 365 Users
  3. Connecting the app to Dataverse
  4. Running and publishing app

1. Prerequisites: Preparing Development Environment

✔ Required Tools:

✔ Required Power Platform Setup:

Enable Code Apps by navigating to:

Power Platform Admin Center → Environment → Settings → Features → Power Apps Code Apps


2. Create a Power Apps Code App

Step 1 — Scaffold a project

npx degit github:microsoft/PowerAppsCodeApps/templates/vite my-code-app
cd my-code-app

Step 2 — Install dependencies

npm install

Step 3 — Sign into Power Platform using CLI

pac auth create

Step 4 — Select development environment

pac env select --environment https://crmoncetraining.crm8.dynamics.com/

Step 5 — Initialize as a Code App

pac code init --displayname "My Code App"

Step 6 — Run Code App Locally

npm run dev

Step 7 — Build and Push to Power Apps

npm run build
pac code push

3. Connect Code App to Office 365 Users

Office 365 Users allows app to access:

Step 1 — Create or verify an Office 365 Users connection

Go to: Power Apps → Data → Connections → New Connection → Office 365 Users

Step 2 — Find the connector’s connection ID

pac connection list

Step 3 — Add Office 365 Users as a data source

pac code add-data-source -a shared_office365users -c <connectionId>

Example with connection:

pac code add-data-source -a shared_office365users -c c3cd32ef7d424bd78114077f9fecf865

Step 4 — Add Office 365 Users Code in src/App.tsx

import { useState, useEffect } from "react"
import "./App.css"
import { Office365UsersService } from "./generated/services/Office365UsersService"

function App() {
  const [count, setCount] = useState(0)
  const [userName, setUserName] = useState("")
  const [userEmail, setUserEmail] = useState("")
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState("")

  useEffect(() => {
    const testConnection = async () => {
      try {
        const response = await Office365UsersService.MyProfile()
        setUserName(response.data.DisplayName ?? "Unknown")
        setUserEmail(response.data.Mail ?? "Not available")
      } catch (err) {
        setError("Failed to connect to Office 365 Users")
      } finally {
        setLoading(false)
      }
    }
    testConnection()
  }, [])

  return (
    <div style={{ padding: "24px", maxWidth: "600px", margin: "0 auto" }}>
      <h1>My First Power Apps Code App 🚀</h1>
      <div>
        {loading ? "Checking connection..." : error ? error : `Name: ${userName}, Email: ${userEmail}`}
      </div>
      <div>
        <p>Button clicked: {count} times</p>
        <button onClick={() => setCount(count + 1)}>Click Me</button>
      </div>
    </div>
  )
}

export default App

4. Connect Code App to Microsoft Dataverse (CRUD)

Step 1 — Add a Dataverse table as a data source

pac code add-data-source -a dataverse -t adcrm_employee_admin

The following files are generated automatically:

Step 2 — Add Dataverse CRUD Code in src/App.tsx

import { useState, useEffect } from "react"
import "./App.css"
import { Office365UsersService } from "./generated/services/Office365UsersService"
import { Adcrm_employee_adminsService } from "./generated/services/Adcrm_employee_adminsService"

function App() {
  const [userName, setUserName] = useState("")
  const [userEmail, setUserEmail] = useState("")
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState("")

  const [employees, setEmployees] = useState<any[]>([])
  const [employeeName, setEmployeeName] = useState("")
  const [email, setEmail] = useState("")
  const [department, setDepartment] = useState("")
  const [phone, setPhone] = useState("")
  const [editId, setEditId] = useState<string | null>(null)

  useEffect(() => {
    const testConnection = async () => {
      try {
        const response = await Office365UsersService.MyProfile()
        setUserName(response.data.DisplayName ?? "Unknown")
        setUserEmail(response.data.Mail ?? "Unknown")
      } catch {
        setError("Failed to connect to Office 365 Users")
      } finally { setLoading(false) }
    }

    testConnection()
    loadEmployees()
  }, [])

  async function loadEmployees() {
    const result = await Adcrm_employee_adminsService.getAll()
    setEmployees(result.data ?? [])
  }

  async function createEmployee() {
    if (!employeeName) return alert("Employee Name is required")
    try {
    await Adcrm_employee_adminsService.create({
      adcrm_newcolumn: employeeName,
      adcrm_email: email,
      adcrm_department: department,
      adcrm_phone: phone,
    } as any)
    setEmployeeName("")
    setEmail("")
    setDepartment("") 
    setPhone("")
    loadEmployees()
  } catch (err) {
      console.error("Create failed:", err)
      alert("Failed to add employee. Check console for details.")
    }
  }

  function startEdit(emp: any) {
    setEditId(emp.adcrm_employee_adminid)
    setEmployeeName(emp.adcrm_newcolumn)
    setEmail(emp.adcrm_email)
    setDepartment(emp.adcrm_department)
    setPhone(emp.adcrm_phone)
  }

  async function updateEmployee() {
    if (!editId) return
    if (!employeeName) return alert("Employee Name is required")
    try {
    await Adcrm_employee_adminsService.update(editId, {
      adcrm_newcolumn: employeeName,
      adcrm_email: email,
      adcrm_department: department,
      adcrm_phone: phone,
    } as any)
    
    setEditId(null)
    setEmployeeName("")
    setEmail("")
    setDepartment("")
    setPhone("")
    loadEmployees()
    } catch (err) {
      console.error("Update failed:", err)
      alert("Failed to update employee. Check console for details.")
    }
  }


  async function deleteEmployee(id: string) {
    if (!window.confirm("Are you sure you want to delete this employee?")) return

    try {
      await Adcrm_employee_adminsService.delete(id)
      console.log("Deleted record:", id)
      loadEmployees() // refresh table
    } catch (err) {
      console.error("Delete failed:", err)
      alert("Delete failed. Check console for details.")
    }
  }


  return (
    <div style={{ padding: "24px", maxWidth: "900px", margin: "0 auto" }}>
      <h1>My First Power Apps Code App 🚀</h1>

      <div>
        {loading ? "Checking connection..." : error ? error : `Name: ${userName}, Email: ${userEmail}`}
      </div>

      <div>
        <h2>Dataverse Employee Admin (CRUD)</h2>

        <div style={{ display: "flex", gap: "8px", marginBottom: "12px" }}>
          <input placeholder="Employee Name" value={employeeName} onChange={e => setEmployeeName(e.target.value)} />
          <input placeholder="Email" value={email} onChange={e => setEmail(e.target.value)} />
          <input placeholder="Department" value={department} onChange={e => setDepartment(e.target.value)} />
          <input placeholder="Phone" value={phone} onChange={e => setPhone(e.target.value)} />
          {editId ? <button onClick={updateEmployee}>Update</button> : <button onClick={createEmployee}>Add</button>}
        </div>

        <table>
          <thead><tr><th>Name</th><th>Email</th><th>Dept</th><th>Phone</th><th>Actions</th></tr></thead>
          <tbody>
            {employees.map(emp => <tr key={emp.adcrm_employee_adminid}>
              <td>{emp.adcrm_newcolumn}</td>
              <td>{emp.adcrm_email}</td>
              <td>{emp.adcrm_department}</td>
              <td>{emp.adcrm_phone}</td>
              <td>
                <button onClick={() => startEdit(emp)}>Edit</button>
                <button onClick={() => deleteEmployee(emp.adcrm_employee_adminid)} style={{ marginLeft: "10px", color: "red" }}>Delete</button>
              </td>
            </tr>)}
          </tbody>
        </table>
      </div>
    </div>
  )
}

export default App

5. Build and Publish Code App

Once development is complete:

Step 1 — Build production version

npm run build

Step 2 — Publish to Power Apps

pac code push