DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • The Tectonic AI Platform: A Framework for Taming App Sprawl and Data Fragmentation
  • SelfService HR Dashboards with Workday Extend and APIs
  • How We Reduced LCP by 75% in a Production React App
  • Shipping GenAI Into an Existing App: How to Integrate AI Features Without Rewriting Your Stack

Trending

  • Building a Runtime Control Plane for Agentic AI: Lessons From Shipping Real Agents in Production
  • Add Observability to Your React Native Application in 5 Minutes
  • Real-World Problems Being Solved by Java
  • API Facade vs. Orchestration vs. Eventing, Now With AI in the Loop

Adding an Easter Egg to Your App

A Zone Leader talks about how he added a simple "Easter Egg" to an application he built for a family member.

By 
John Vester user avatar
John Vester
DZone Core CORE ·
May. 28, 20 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
9.3K Views

Join the DZone community and get the full member experience.

Join For Free

Those growing up in North America likely have a memory of the Easter Bunny — a mythical creature that magically left baskets or eggs filled with prizes for children. The concept of an Easter Egg Hunt pairs a group of children with a large area filled with hidden eggs. In some cases, the child with the most eggs found wins a prize. In other cases, the child which finds the single "golden egg" wins a prize too.

As you might expect, this idea of putting undocumented features (Easter Eggs) into a software program was destined to happen. Over the years, I have found myself seeking out such hidden gems and finally decided to add one into my mother-in-law's application as noted in my "New Application Journey" series.

Determining the Egg

For me, determining the content of the Easter Egg was simple.  I wanted to replace the link behind the logo of the application to return a modal filled with random content from a collection of Instagram accounts. Once found, end-users of the application (which is basically just my mother-in-law) could see a random photo from one of our family members just by clicking the top left corner of her application:

Application navbar

API Updates

For the content retrieval of the Easter Egg, I decided I would use the Spring Boot RESTful API to create EasterEggData  to be used by the Angular client:

Java
 




x
12


 
1
@NoArgsConstructor
2
@Data
3
public class EasterEggData {
4
    private String url;
5
    private String caption;
6
    private Calendar timestamp;
7
 
          
8
    @Override
9
    public String toString() {
10
        return "easterEggData=EasterEggData(url=" + url + ", caption=" + caption +", timestamp=" + timestamp.getTime();
11
    }
12
}



The Angular client would then call the /easterEgg URI via a controller in the API project:

Java
 




xxxxxxxxxx
1
18


 
1
@Tag(name = "Easter Egg API")
2
@RequiredArgsConstructor
3
@CrossOrigin
4
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
5
@RestController
6
@PreAuthorize("hasAuthority('AppUser') || #oauth2.hasScope('openid')")
7
public class EasterEggController {
8
    private final EasterEggService easterEggService;
9
 
          
10
    @GetMapping(value = "/easterEgg")
11
    public ResponseEntity<EasterEggData> getEasterEggUrl() {
12
        try {
13
            return new ResponseEntity<>(easterEggService.getEasterEgg(), HttpStatus.OK);
14
        } catch (Exception e) {
15
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
16
        }
17
    }
18
}



Client-Side Updates

On the client-side, I introduced a simple EasterEggService:

JavaScript
 




xxxxxxxxxx
1
16


 
1
@Injectable()
2
export class EasterEggService {
3
    constructor(private http: HttpClient) { }
4
 
          
5
    baseUrl: string = environment.api + '/easterEgg';
6
 
          
7
    getEasterEgg(): Observable<EasterEggData> {
8
        const httpOptions = {
9
            headers: new HttpHeaders({
10
                'Authorization': 'Bearer ' + myToken
11
            })
12
        };
13
 
          
14
        return this.http.get<EasterEggData>(this.baseUrl, httpOptions);
15
    }
16
}



I created EasterEggData on the client-side:

JavaScript
 




xxxxxxxxxx
1


 
1
export class EasterEggData {
2
    url: string;
3
    caption: string;
4
    timestamp: number;
5
 
          
6
    constructor() {}
7
}



Then, I wired the logo link to the following component:

Java
 




xxxxxxxxxx
1
12


 
1
export class EasterEggModalComponent implements OnInit {
2
    easterEggData: EasterEggData;
3
 
          
4
    constructor(public activeModal: NgbActiveModal, private easterEggService: EasterEggService) { }
5
 
          
6
    async ngOnInit() {
7
        this.easterEggData = new EasterEggData();
8
        this.easterEggService.getEasterEgg().subscribe(data => {
9
            this.easterEggData = data;
10
        });
11
    }
12
}



Service Updates

With the basic wiring in place, I just needed to create the service-level work to populate the EasterEggData object. Without revealing the source of my personal data, the core processing logic is shown below:

Java
 




xxxxxxxxxx
1
20


 
1
@Override
2
public EasterEggData getEasterEgg() throws AmhsException {
3
   log.debug("getEasterEgg()");
4
   EasterEggData easterEggData = new EasterEggData();
5
6
   List<InstagramData.Edges> instagramData = getInstagramData();
7
8
   if (CollectionUtils.isNotEmpty(instagramData)) {
9
      RandomGenerator<InstagramData.Edges> randomGenerator = new RandomGenerator<>();
10
      List<InstagramData.Edges> edges = randomGenerator.randomize(instagramData, 1);
11
12
      easterEggData.setUrl(edges.get(0).getNode().getDisplay_url());
13
      easterEggData.setCaption(edges.get(0).getNode()                     
14
         .getEdge_media_to_caption().getEdges().get(0).getNode().getText());
15
      easterEggData.setTimestamp(edges.get(0).getNode().getTimeStamp());
16
   }
17
18
   log.info("easterEggData={}", easterEggData);
19
   return easterEggData;
20
}



In the example above, I am actually using RandomGenerator as discussed in my "Building a Random Generator" series. In this case, there is a List<InstagramData> that is being retrieved. The randomize() method will return one item, at random, from this list and convert it to an EasterEggData object.

Conclusion

When my mother-in-law clicks the logo link of her application, she will now see something like this:

Example Easter Egg

Clicking the logo again will show something like this:

Example Easter Egg

Every time the modal is requested in Angular, the image, caption, and original post date are all from a random Instagram post from one of our family members' accounts. My mother-in-law doesn't get out to Instagram very often, so this gives her a quick way to check in to see what she may have missed.

Have a really great day!

EGG (file format) app

Opinions expressed by DZone contributors are their own.

Related

  • The Tectonic AI Platform: A Framework for Taming App Sprawl and Data Fragmentation
  • SelfService HR Dashboards with Workday Extend and APIs
  • How We Reduced LCP by 75% in a Production React App
  • Shipping GenAI Into an Existing App: How to Integrate AI Features Without Rewriting Your Stack

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook