skip to Main Content

I am calling a php file from an angular front end.

The php file checks for tweets every ten minutes, and after this time updates a json file which is then called from angular. I have an angular factory with 2 methods. The first method, called updateTwitter() makes a GET request to the php file which then makes a GET request to Twitter and returns tweets. These are then written to a JSON file. The second method fetchTwitter() makes a GET request to this JSON file and displays the data on the front end.

My question is how should I call these methods in my controller. I feel I should use a promise, and say something like, until the first method (updateTwitter()) has finished don't runfecthTwitter()`. Is this the correct approach, and if so , how should I write this?

My code looks like this.

php

<?php
require_once('twitter_proxy.php');
// Twitter OAuth Config options
$oauth_access_token = '*****';
$oauth_access_token_secret = '*****';
$consumer_key = '*****';
$consumer_secret = '*****';
$user_id = '*****';
$screen_name = 'StackOverflow';
$count = 5;
$twitter_url = 'statuses/user_timeline.json';
$twitter_url .= '?user_id=' . $user_id;
$twitter_url .= '&screen_name=' . $screen_name;
$twitter_url .= '&count=' . $count;
// Create a Twitter Proxy object from our twitter_proxy.php class
$twitter_proxy = new TwitterProxy(
    $oauth_access_token,            // 'Access token' on https://apps.twitter.com
    $oauth_access_token_secret,     // 'Access token secret' on https://apps.twitter.com
    $consumer_key,                  // 'API key' on https://apps.twitter.com
    $consumer_secret,               // 'API secret' on https://apps.twitter.com
    $user_id,                       // User id (http://gettwitterid.com/)
    $screen_name,                   // Twitter handle
    $count                          // The number of tweets to pull out
);

function checkForUpdates($twitter_proxy, $twitter_url) {
    $tweets = $twitter_proxy->get($twitter_url);
    $data = array ('twitter_result' => $tweets, 'timestamp' => time());
    file_put_contents('twitter_result.json', json_encode($data));
}

//check if the file exists
if(!file_exists('twitter_result.json')) {
    //Invoke the get method to retrieve results via a cURL request
    //and create a file with timestamp containing tweets
    checkForUpdates($twitter_proxy, $twitter_url);

}else {
    //if file exists check it has not been updated in 10 minutes
    //if not update the tweets and timestamp
    $data = json_decode(file_get_contents('twitter_result.json'));
    if ($data->{"timestamp"} > (time() - 10 * 60)) {
        checkForUpdates($twitter_proxy, $twitter_url);
    }
}

Angular code

factory.js

//factory used to make GET request to Instagram
app.factory('socialMedia', ['$http', function($http){
return {

    updateTwitter: function() {
        return $http({
            url: 'get_tweets.php',
            method: 'GET'
        })
    },
    fetchTwitter: function() {
        return $http({
            url: 'twitter_result.json',
            method: 'GET'
        })
    }
}

controller.js

app.controller("testCtrl", ["$routeParams", "socialMedia", function ($routeParams, socialMedia) {

    testCtrl = this;
    this.twitterPosts = [];

    socialMedia.updateTwitter();

    socialMedia.fetchTwitter().success(function(data){
        socialMedia.updateTwitter();
        var result = JSON.parse(data.twitter_result);
        for(var i = 0; i < result.length; i++){
            testCtrl.twitterPosts.push(result[i]);
        }      
    })
    .error(function () {
        testCtrl.loading = false;
        testCtrl.error = true;
    });
}]);

2

Answers


  1. Since the $http.get method returns the promise you can easily chain your calls like this:

    socialMedia.updateTwitter()
    .then(function() {
        socialMedia.fetchTwitter()
        .then(function(data){
            ...
        })
    });
    

    Also note, according to the $http documentation:

    The $http legacy promise methods success and error have been deprecated. Use the standard then method instead

    Hence, your controller should look the following way:

    app.controller("testCtrl", ["$routeParams", "socialMedia", function ($routeParams, socialMedia) {
        testCtrl = this;
        this.twitterPosts = [];
    
        socialMedia.updateTwitter()
        .then(function(){
            socialMedia.fetchTwitter()
            .then(function(response){
                var data = response.data;
                var result = JSON.parse(data.twitter_result);
                for(var i = 0; i < result.length; i++){
                    testCtrl.twitterPosts.push(result[i]);
                }      
            })
            .catch(function(error){
                testCtrl.loading = false;
                testCtrl.error = true;
            });
        });
    }]);
    
    Login or Signup to reply.
  2. Yes, that’d be a good approach. Execute the second request as a callback for the first one or chain them using the promise’s .then() method.
    But why aren’t you just passing the data in the first request’s response instead of doing another second request?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search